Initial commit of Command & Conquer Red Alert source code.
This commit is contained in:
512
WIN32LIB/SRCDEBUG/ALLOC.CPP
Normal file
512
WIN32LIB/SRCDEBUG/ALLOC.CPP
Normal file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : ALLOC.CPP *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : February 1, 1992 *
|
||||
* *
|
||||
* Last Update : March 9, 1995 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Alloc -- Allocates system RAM. *
|
||||
* Ram_Free -- Determines the largest free chunk of RAM. *
|
||||
* Free -- Free an Alloc'ed block of RAM. *
|
||||
* Resize_Alloc -- Change the size of an allocated block. *
|
||||
* Heap_Size -- Size of the heap we have. *
|
||||
* Total_Ram_Free -- Total amount of free RAM. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
#include <bios.h>
|
||||
|
||||
|
||||
#ifndef WWMEM_H
|
||||
#include "wwmem.h"
|
||||
#endif
|
||||
|
||||
|
||||
extern "C" unsigned long Largest_Mem_Block ( void ) ;
|
||||
|
||||
/*
|
||||
** Define the equates necessary to call a DPMI interrupt.
|
||||
*/
|
||||
#define DPMI_INT 0x0031
|
||||
#define DPMI_LOCK_MEM 0x0600
|
||||
#define DPMI_UNLOCK_MEM 0x0601
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
unsigned long MinRam=0L; // Record of least memory at worst case.
|
||||
unsigned long MaxRam=0L; // Record of total allocated at worst case.
|
||||
static unsigned long TotalRam = 0L;
|
||||
static unsigned long Memory_Calls = 0L;
|
||||
|
||||
void (*Memory_Error)(void) = NULL;
|
||||
extern void (*Memory_Error_Exit)(char *string)=NULL;
|
||||
|
||||
|
||||
//#define MEM_CHECK
|
||||
|
||||
#ifdef MEM_CHECK
|
||||
extern "C"{
|
||||
extern void __cdecl Int3(void);
|
||||
}
|
||||
#endif //MEM_CHECK
|
||||
|
||||
/***************************************************************************
|
||||
* DPMI_LOCK -- handles locking a block of DPMI memory *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
#include"mono.h"
|
||||
void DPMI_Lock(VOID const *, long const )
|
||||
{
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* DPMI_UNLOCK -- Handles unlocking a locked block of DPMI *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void DPMI_Unlock(void const *, long const )
|
||||
{
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Alloc -- Allocates system RAM. *
|
||||
* *
|
||||
* This is the basic RAM allocation function. It is used for all *
|
||||
* memory allocations needed by the system or the main program. *
|
||||
* *
|
||||
* INPUT: bytes_to_alloc -- LONG value of the number of bytes to alloc. *
|
||||
* *
|
||||
* flags -- Memory allocation control flags. *
|
||||
* MEM_NORMAL: No special flags. *
|
||||
* MEM_CLEAR: Zero out memory block. *
|
||||
* MEM_NEW: Called by a new. *
|
||||
* *
|
||||
* OUTPUT: Returns with pointer to allocated block. If NULL was returned *
|
||||
* it indicates a failure to allocate. Note: NULL will never be *
|
||||
* returned if the standard library allocation error routine is *
|
||||
* used. *
|
||||
* *
|
||||
* WARNINGS: If you replace the standard memory allocation error routine *
|
||||
* and make it so that Alloc CAN return with a NULL, be sure *
|
||||
* and check for this in your code. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/03/1991 JLB : Documented. *
|
||||
* 08/09/1993 JLB : Updated with EMS memory support. *
|
||||
* 04/28/1994 JAW : Updated to 32bit Protected mode. *
|
||||
* 03/09/1995 JLB : Fixed *
|
||||
* 09/28/1995 ST : Simplified for win95 *
|
||||
*=========================================================================*/
|
||||
void *Alloc(unsigned long bytes_to_alloc, MemoryFlagType flags)
|
||||
{
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
void *mem_ptr;
|
||||
|
||||
#ifdef MEM_CHECK
|
||||
bytes_to_alloc += 32;
|
||||
#endif //MEM_CHECK
|
||||
|
||||
mem_ptr = malloc ( bytes_to_alloc );
|
||||
|
||||
if ( !mem_ptr && Memory_Error ){
|
||||
Memory_Error();
|
||||
}
|
||||
|
||||
if ( mem_ptr && ( flags & MEM_CLEAR ) ){
|
||||
memset ( mem_ptr , 0 , bytes_to_alloc );
|
||||
}
|
||||
|
||||
#ifdef MEM_CHECK
|
||||
mem_ptr = (void*)((char*)mem_ptr + 16);
|
||||
unsigned long *magic_ptr =(unsigned long*) ( ((char *)mem_ptr) - 16 );
|
||||
*magic_ptr++ = (unsigned long)mem_ptr;
|
||||
*magic_ptr++ = (unsigned long)mem_ptr;
|
||||
*magic_ptr++ = (unsigned long)mem_ptr;
|
||||
*magic_ptr = bytes_to_alloc - 32;
|
||||
magic_ptr = (unsigned long*) ( ((char*)mem_ptr) + bytes_to_alloc - 32 );
|
||||
*magic_ptr++ = (unsigned long)mem_ptr;
|
||||
*magic_ptr++ = (unsigned long)mem_ptr;
|
||||
*magic_ptr++ = (unsigned long)mem_ptr;
|
||||
*magic_ptr = (unsigned long)mem_ptr;
|
||||
#endif //MEM_CHECK
|
||||
|
||||
Memory_Calls++;
|
||||
return ( mem_ptr );
|
||||
|
||||
#else
|
||||
|
||||
|
||||
|
||||
union REGS regs ;
|
||||
struct SREGS sregs ;
|
||||
unsigned char *retval=NULL; // Pointer to allocated block.
|
||||
unsigned long original_size; // Original allocation size.
|
||||
unsigned long bytesfree; // Number of free bytes.
|
||||
long *longptr=NULL; // Pointer used to store selector
|
||||
|
||||
/*
|
||||
** Save the original allocated space size so that we can clear the
|
||||
** exact amount of RAM if they specified MEM_CLEAR.
|
||||
*/
|
||||
original_size = bytes_to_alloc;
|
||||
|
||||
/*
|
||||
** Reserve one byte for the header of the memory we allocated.
|
||||
** We will store the flags variable there for later use.
|
||||
*/
|
||||
bytes_to_alloc += (flags & MEM_LOCK) ? 5 : 1;
|
||||
|
||||
/*
|
||||
** Initialize the total ram available value.
|
||||
*/
|
||||
if (!TotalRam) {
|
||||
TotalRam = Total_Ram_Free(MEM_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
// Try to allocate the memory out of the protected mode memory
|
||||
// chain if we did not require a real mode allocation. If this
|
||||
// fails we will have to try to allocate it out of real mode memory.
|
||||
// Real mode memory is a last resort because some types of applications
|
||||
// require real mode memory.
|
||||
if (!(flags & MEM_REAL)) {
|
||||
retval = (unsigned char*)malloc(bytes_to_alloc);
|
||||
}
|
||||
|
||||
// Try to allocate the memory out of the real mode memory using DPMI
|
||||
// service 0x100. Note that retval will be null if we are requesting
|
||||
// real mode memory so that we do not have to explicitly check for the
|
||||
// real mode flag. Remember we need to reserve room for the dos
|
||||
// selector value at the beginning of our allocated block so rather than
|
||||
// adding fifteen and rounding, we need to add 19 and round.
|
||||
if (!retval) {
|
||||
flags = (MemoryFlagType)(flags | MEM_REAL);
|
||||
regs.x.eax = 0x100;
|
||||
regs.x.ebx = (bytes_to_alloc + 19) >> 4;
|
||||
if (regs.x.ebx & 0xFFFF0000) {
|
||||
retval = NULL;
|
||||
} else {
|
||||
segread ( & sregs ) ;
|
||||
int386x ( 0x31 , & regs, & regs , & sregs ) ;
|
||||
if (regs.x.cflag)
|
||||
retval = NULL;
|
||||
else {
|
||||
longptr = (long *)(((regs.x.eax & 0xFFFF) << 4)+ 1);
|
||||
*longptr++ = regs.x.edx & 0xFFFF;
|
||||
retval = (unsigned char *)longptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the alloc failed then we need to signify a memory error.
|
||||
if (retval == NULL) {
|
||||
if(Memory_Error != NULL)
|
||||
Memory_Error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If the memory needs to be DPMI locked then we should store the
|
||||
// original size in the header before we store the flags.
|
||||
if (flags & MEM_LOCK) {
|
||||
longptr = (long *)retval;
|
||||
*longptr++ = original_size;
|
||||
retval = (unsigned char *)longptr;
|
||||
}
|
||||
|
||||
|
||||
// Now that we know the alloc was sucessful (and for an extra byte
|
||||
// more than the user wanted) we need to stick in the memory flags.
|
||||
*retval++ = flags;
|
||||
|
||||
// If the memory needed to be DPMI locked then set it up so it
|
||||
// is locked.
|
||||
if (flags & MEM_LOCK) {
|
||||
DPMI_Lock(retval, original_size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Clear the space if they wanted it clear */
|
||||
|
||||
if (flags & MEM_CLEAR) {
|
||||
unsigned char *ptr; // Working memory block pointer.
|
||||
|
||||
ptr = retval;
|
||||
memset(ptr, '\0', original_size);
|
||||
}
|
||||
|
||||
bytesfree = Total_Ram_Free(MEM_NORMAL);
|
||||
if (bytesfree < MinRam) {
|
||||
MinRam = bytesfree;
|
||||
}
|
||||
if (TotalRam-bytesfree > MaxRam) {
|
||||
MaxRam = TotalRam-bytesfree;
|
||||
}
|
||||
|
||||
Memory_Calls++;
|
||||
|
||||
return(retval);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Free -- Free an Alloc'ed block of RAM. *
|
||||
* *
|
||||
* FUNCTION: *
|
||||
* *
|
||||
* INPUT: A pointer to a block of RAM from Alloc. *
|
||||
* *
|
||||
* OUTPUT: None. *
|
||||
* *
|
||||
* WARNINGS: Don't use this for an Alloc_Block'ed RAM block. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/25/1990 : Created. *
|
||||
***************************************************************************/
|
||||
#ifdef WIN32
|
||||
|
||||
void Free(void const *pointer)
|
||||
{
|
||||
|
||||
if ( pointer ){
|
||||
|
||||
#ifdef MEM_CHECK
|
||||
|
||||
unsigned long *magic_ptr = (unsigned long*) ( ((char*)pointer) - 16 );
|
||||
|
||||
if (*magic_ptr++ != (unsigned long)pointer ||
|
||||
*magic_ptr++ != (unsigned long)pointer ||
|
||||
*magic_ptr++ != (unsigned long)pointer ){
|
||||
Int3();
|
||||
}
|
||||
|
||||
magic_ptr = (unsigned long*) ( ((char*)pointer) + *magic_ptr );
|
||||
|
||||
if (*magic_ptr++ != (unsigned long)pointer ||
|
||||
*magic_ptr++ != (unsigned long)pointer ||
|
||||
*magic_ptr++ != (unsigned long)pointer ||
|
||||
*magic_ptr++ != (unsigned long)pointer ){
|
||||
Int3();
|
||||
}
|
||||
|
||||
pointer = (void*) (((char*)pointer)-16);
|
||||
#endif //MEM_CHECK
|
||||
|
||||
free ( (void*)pointer );
|
||||
Memory_Calls--;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void Free(void const *pointer)
|
||||
{
|
||||
|
||||
union REGS regs ;
|
||||
struct SREGS sregs ;
|
||||
|
||||
|
||||
if (pointer) {
|
||||
/*
|
||||
** Get a pointer to the flags that we stored off.
|
||||
*/
|
||||
char *byteptr = ((char *)pointer) - 1;
|
||||
|
||||
/*
|
||||
** Check to see if this was locked me and if it was unlock it.
|
||||
*/
|
||||
if (*byteptr & MEM_LOCK) {
|
||||
long *longptr = ((long *)byteptr) - 1;
|
||||
DPMI_Unlock(pointer, *longptr);
|
||||
pointer = (void *)longptr;
|
||||
} else
|
||||
pointer = (void *)byteptr;
|
||||
|
||||
|
||||
// If the pointer is a real mode pointer than it will point to the
|
||||
// first megabyte of system memory. If it does than we need to
|
||||
// use DPMI to free it.
|
||||
if (*byteptr & MEM_REAL) {
|
||||
regs.x.eax = 0x101;
|
||||
regs.x.edx = *(((long *)pointer) - 1);
|
||||
segread ( & sregs ) ;
|
||||
int386x(0x31, ®s, ®s, &sregs);
|
||||
} else {
|
||||
free((void *)pointer);
|
||||
}
|
||||
Memory_Calls--;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Resize_Alloc -- Change the size of an allocated block. *
|
||||
* *
|
||||
* This routine will take a previously allocated block and change its *
|
||||
* size without unnecessarily altering its contents. *
|
||||
* *
|
||||
* INPUT: pointer -- Pointer to the original memory allocation. *
|
||||
* *
|
||||
* new_size -- Size in bytes that it will be converted to. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the new allocation. *
|
||||
* *
|
||||
* WARNINGS: ??? *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/01/1992 JLB : Commented. *
|
||||
*=========================================================================*/
|
||||
void *Resize_Alloc(void *original_ptr, unsigned long new_size_in_bytes)
|
||||
{
|
||||
|
||||
unsigned long *temp;
|
||||
|
||||
temp = (unsigned long*)original_ptr;
|
||||
|
||||
/* ReAlloc the space */
|
||||
temp = (unsigned long *)realloc(temp, new_size_in_bytes);
|
||||
if (temp == NULL) {
|
||||
if(Memory_Error != NULL)
|
||||
Memory_Error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return(temp);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Ram_Free -- Determines the largest free chunk of RAM. *
|
||||
* *
|
||||
* Use this routine to determine the largest free chunk of available *
|
||||
* RAM for allocation. It also performs a check of the memory chain. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: Returns with the size of the largest free chunk of RAM. *
|
||||
* *
|
||||
* WARNINGS: This does not return the TOTAL memory free, only the *
|
||||
* largest free chunk. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/03/1991 JLB : Commented. *
|
||||
*=========================================================================*/
|
||||
long Ram_Free(MemoryFlagType)
|
||||
{
|
||||
// return(_memmax());
|
||||
#if(0)
|
||||
MEMORYSTATUS mem_info;
|
||||
mem_info.dwLength=sizeof(mem_info);
|
||||
GlobalMemoryStatus(&mem_info);
|
||||
return ( mem_info.dwAvailPhys );
|
||||
#endif
|
||||
return ( 64*1024*1024 );
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Heap_Size -- Size of the heap we have. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
long Heap_Size(MemoryFlagType )
|
||||
{
|
||||
if (!TotalRam) {
|
||||
TotalRam = Total_Ram_Free(MEM_NORMAL);
|
||||
}
|
||||
return(TotalRam);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Total_Ram_Free -- Total amount of free RAM. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1994 SKB : Created. *
|
||||
* 03/09/1995 JLB : Uses prerecorded heap size maximum. *
|
||||
*=========================================================================*/
|
||||
long Total_Ram_Free(MemoryFlagType )
|
||||
{
|
||||
#if(0)
|
||||
MEMORYSTATUS mem_info;
|
||||
mem_info.dwLength=sizeof(mem_info);
|
||||
GlobalMemoryStatus(&mem_info);
|
||||
return ( mem_info.dwAvailPhys );
|
||||
#endif
|
||||
|
||||
return ( 64*1024*1024 );
|
||||
}
|
||||
|
||||
298
WIN32LIB/SRCDEBUG/APROFILE.ASM
Normal file
298
WIN32LIB/SRCDEBUG/APROFILE.ASM
Normal file
@@ -0,0 +1,298 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Profiler *
|
||||
;* *
|
||||
;* File Name : APROFILE.ASM *
|
||||
;* *
|
||||
;* Programmer : Steve Tall *
|
||||
;* *
|
||||
;* Start Date : November 17th, 1995 *
|
||||
;* *
|
||||
;* Last Update : November 20th, 1995 [ST] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* __PRO -- must be called at the beginning of each function *
|
||||
;* __EPI -- must be called at the end of each function *
|
||||
;* Copy_CHL -- initialise the profiler asm data *
|
||||
;* Profiler_Callback -- windows callback for millisecond timer *
|
||||
;* *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
|
||||
p386
|
||||
model flat
|
||||
ideal
|
||||
jumps
|
||||
|
||||
|
||||
MAX_PROFILE_TIME = 60*1 ;1 minute(s)
|
||||
PROFILE_RATE = 1000 ;1000 samples per sec
|
||||
|
||||
|
||||
;
|
||||
; Externs
|
||||
;
|
||||
;
|
||||
global C ProfileFunctionAddress:dword
|
||||
global C ProfilePtr:dword
|
||||
global C ProfileList:dword
|
||||
global C Stop_Profiler:near
|
||||
global New_Profiler_Callback_:near
|
||||
global Old_Profiler_Callback_:near
|
||||
global C Profile_Init:near
|
||||
global C Profile_End:near
|
||||
global ___begtext:near
|
||||
global BaseAddress:dword
|
||||
global __PRO:near
|
||||
global __EPI:near
|
||||
global MyStack:dword
|
||||
global MyStackPtr:dword
|
||||
global ProAddress:dword
|
||||
global EpiAddress:dword
|
||||
|
||||
|
||||
codeseg
|
||||
|
||||
|
||||
;*********************************************************************************************
|
||||
;* __PRO -- registers the current procedure *
|
||||
;* *
|
||||
;* INPUT: Nothing *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* Warnings: *
|
||||
;* Assumes that ss:Esp points to return address in function to be registered *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/95 4:39PM ST : Created. *
|
||||
;*===========================================================================================*
|
||||
|
||||
proc __PRO near
|
||||
|
||||
jmp [ProAddress]
|
||||
; safe version of prologue code
|
||||
Pro_Start: push eax
|
||||
mov eax,[MyStackPtr]
|
||||
push [ProfileFunctionAddress]
|
||||
pop [eax*4+MyStack]
|
||||
inc [MyStackPtr]
|
||||
pop eax
|
||||
push [dword ss:esp]
|
||||
pop [ProfileFunctionAddress]
|
||||
Pro_End: ret
|
||||
|
||||
; unsafe (but much faster) prologue code
|
||||
; pop [ProfileFunctionAddress]
|
||||
; jmp [ProfileFunctionAddress]
|
||||
|
||||
endp __PRO
|
||||
|
||||
|
||||
;*********************************************************************************************
|
||||
;* __EPI -- Registers the privious procedure as current again *
|
||||
;* *
|
||||
;* INPUT: Nothing *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* Warnings: *
|
||||
;* Assumes that calling procedure will pop ebp immediately on return so we dont have to *
|
||||
;* preserve it. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/95 4:42PM ST : Created. *
|
||||
;*===========================================================================================*
|
||||
|
||||
proc __EPI near
|
||||
|
||||
jmp [EpiAddress]
|
||||
; Safe version of epilogue code. Uncomment the push and pop for ultimate safety
|
||||
Epi_Start: dec [MyStackPtr]
|
||||
; push ebp
|
||||
mov ebp,[MyStackPtr]
|
||||
mov ebp,[ebp*4+MyStack]
|
||||
mov [ProfileFunctionAddress],ebp
|
||||
; pop ebp
|
||||
Epi_End: ret
|
||||
|
||||
; Unsafe (but much faster) epilogue code. Makes lots of assumptions.
|
||||
; push [dword esp+8]
|
||||
; pop [ProfileFunctionAddress]
|
||||
; ret
|
||||
|
||||
endp __EPI
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************************
|
||||
;* Profile_Init -- Initialises the .asm data required for profile session *
|
||||
;* *
|
||||
;* INPUT: Nothing *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* Warnings: *
|
||||
;* Assumes that '___begtext' is the first label in the code segment and that its *
|
||||
;* address is within 15 bytes of the start of the code segment *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/95 4:44PM ST : Created. *
|
||||
;*===========================================================================================*
|
||||
|
||||
proc Profile_Init C near
|
||||
|
||||
mov eax,offset ___begtext
|
||||
and eax,0fffffff0h
|
||||
mov [BaseAddress],eax
|
||||
;mov [MyStackPtr],0
|
||||
mov [ProfileList],PROFILE_RATE
|
||||
mov [ProfilePtr],1
|
||||
mov [ProAddress],offset Pro_Start
|
||||
mov [EpiAddress],offset Epi_Start
|
||||
ret
|
||||
|
||||
endp Profile_Init
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************************
|
||||
;* Profile_End -- disables the __PRO and __EPI procedures *
|
||||
;* *
|
||||
;* INPUT: Nothing *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* Warnings: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/95 4:44PM ST : Created. *
|
||||
;*===========================================================================================*
|
||||
|
||||
proc Profile_End C near
|
||||
|
||||
mov [ProAddress],offset Pro_End
|
||||
mov [EpiAddress],offset Epi_End
|
||||
ret
|
||||
|
||||
endp Profile_End
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************************
|
||||
;* New_Profiler_Callback -- Windows callback used to register function hits *
|
||||
;* *
|
||||
;* INPUT: Nothing *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* Note: *
|
||||
;* The frequency that this is called depends on MAX_PROFILE_RATE defined here and in *
|
||||
;* profile.h *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/95 4:47PM ST : Created. *
|
||||
;*===========================================================================================*
|
||||
proc New_Profiler_Callback_ near
|
||||
|
||||
push eax
|
||||
push esi
|
||||
mov esi,[ProfilePtr]
|
||||
cmp esi,MAX_PROFILE_TIME*PROFILE_RATE
|
||||
jge @@out
|
||||
mov eax,[ProfileFunctionAddress]
|
||||
sub eax,[BaseAddress]
|
||||
mov [ProfileList+esi*4],eax
|
||||
inc [ProfilePtr]
|
||||
pop esi
|
||||
pop eax
|
||||
ret
|
||||
|
||||
@@out: call Stop_Profiler
|
||||
pop esi
|
||||
pop eax
|
||||
ret
|
||||
|
||||
endp New_Profiler_Callback_
|
||||
|
||||
|
||||
|
||||
;*********************************************************************************************
|
||||
;* Old_Profiler_Callback -- Windows callback used to register function hits *
|
||||
;* *
|
||||
;* INPUT: Windows timer callback stuff - not used *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* Note: *
|
||||
;* The frequency that this is called depends on MAX_PROFILE_RATE defined here and in *
|
||||
;* profile.h *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/95 4:47PM ST : Created. *
|
||||
;*===========================================================================================*
|
||||
|
||||
proc Old_Profiler_Callback_ near
|
||||
|
||||
push eax
|
||||
push esi
|
||||
mov esi,[ProfilePtr]
|
||||
cmp esi,MAX_PROFILE_TIME*PROFILE_RATE
|
||||
jge @@out
|
||||
mov eax,[ProfileFunctionAddress]
|
||||
sub eax,[BaseAddress]
|
||||
mov [ProfileList+esi*4],eax
|
||||
inc [ProfilePtr]
|
||||
pop esi
|
||||
pop eax
|
||||
ret 14h
|
||||
|
||||
@@out: call Stop_Profiler
|
||||
pop esi
|
||||
pop eax
|
||||
ret 14h
|
||||
|
||||
endp Old_Profiler_Callback_
|
||||
|
||||
|
||||
|
||||
dataseg
|
||||
align 4
|
||||
|
||||
ProfileFunctionAddress dd 0 ;Ptr to function we are currently in
|
||||
BaseAddress dd 0 ;Address of the code segment start
|
||||
MyStackPtr dd 0 ;offset into my stack table
|
||||
ProAddress dd Pro_Start ;jmp ptr for __PRO procedure
|
||||
EpiAddress dd Epi_Start ;jmp ptr for __EPI procedure
|
||||
|
||||
label MyStack dword ;my stack table
|
||||
dd 16*1024 dup (?)
|
||||
|
||||
end
|
||||
374
WIN32LIB/SRCDEBUG/AUDUNCMP.ASM
Normal file
374
WIN32LIB/SRCDEBUG/AUDUNCMP.ASM
Normal file
@@ -0,0 +1,374 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Audio Library *
|
||||
;* *
|
||||
;* File Name : AUDUNCMP.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil W. Gorrow *
|
||||
;* *
|
||||
;* Start Date : March 14, 1995 *
|
||||
;* *
|
||||
;* Last Update : June 26, 1995 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Decompress_Frame_Lock -- locks the JLB audio decompression code *
|
||||
;* Decompress_Frame_Unlock -- Unlocks the JLB audio compression code *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
CODESEG
|
||||
|
||||
DPMI_INTR equ 31h
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
CODE_2BIT EQU 0
|
||||
CODE_4BIT EQU 1
|
||||
CODE_RAW EQU 2
|
||||
CODE_SILENCE EQU 3
|
||||
MAGICNUMBER EQU 00000DEAFh
|
||||
MAGICNUMBER2 EQU 0BABEBABEh
|
||||
|
||||
_2bitdecode DB -2,-1,0,1
|
||||
_4bitdecode DB -9,-8,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,8
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME -- Uncompresses a WW compressed audio frame *
|
||||
;* *
|
||||
;* INPUT: void * source - pointer to encoded audio data *
|
||||
;* void * dest - pointer to decompression area *
|
||||
;* long size - the maximum size of destination buffer *
|
||||
;* *
|
||||
;* OUTPUT: long - the number of bytes we uncompressed *
|
||||
;* *
|
||||
;* PROTO: long Decompress_Frame(void *, void *, long); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/14/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
GLOBAL C Decompress_Frame:NEAR
|
||||
PROC Decompress_Frame C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG count:DWORD
|
||||
|
||||
LOCAL previous:BYTE
|
||||
LOCAL incount:DWORD
|
||||
|
||||
pushfd
|
||||
cld
|
||||
mov [incount],0 ;Bytes read from source
|
||||
|
||||
|
||||
; Source, Dest and count must be valid.
|
||||
|
||||
cmp [source],0
|
||||
je ??fini
|
||||
|
||||
cmp [dest],0
|
||||
je ??fini
|
||||
|
||||
cmp [count],0
|
||||
je ??fini
|
||||
|
||||
mov esi,[source] ;Pointer to source data.
|
||||
mov edi,[dest] ;Pointer to destination data.
|
||||
mov ecx,[count] ;Number of bytes to fill dest buffer.
|
||||
mov dl,080h ;Previous sample (starting value).
|
||||
|
||||
??mainloop:
|
||||
cmp ecx,0 ;If dest full then exit
|
||||
jle ??fini
|
||||
|
||||
xor eax,eax
|
||||
mov al,[esi] ;Get code byte
|
||||
inc [incount]
|
||||
inc esi
|
||||
shl eax,2 ;AH contains code.
|
||||
shr al,2 ;AL contains sub-code data.
|
||||
|
||||
cmp ah,CODE_RAW ;Raw sequence?
|
||||
jne short ??try4bit
|
||||
|
||||
; The code contains either a 5 bit delta or a count of
|
||||
; raw samples to dump out.
|
||||
|
||||
test al,00100000b
|
||||
je short ??justraw
|
||||
|
||||
; The lower 5 bits are actually a signed delta.
|
||||
; Sign extend the delta and add it to the stream.
|
||||
|
||||
shl al,3
|
||||
sar al,3
|
||||
add dl,al
|
||||
mov [edi],dl
|
||||
dec ecx
|
||||
inc edi
|
||||
jmp ??mainloop
|
||||
|
||||
; The lower 5 bits hold a count of the number of raw
|
||||
; samples that follow this code. Dump these samples to
|
||||
; the output buffer.
|
||||
|
||||
??justraw:
|
||||
mov ebx,ecx
|
||||
xor ah,ah
|
||||
inc al
|
||||
mov ecx,eax
|
||||
shr ecx,1
|
||||
rep movsw
|
||||
adc ecx,ecx
|
||||
rep movsb
|
||||
mov ecx,ebx
|
||||
add [incount],eax
|
||||
sub ecx,eax
|
||||
dec edi
|
||||
mov dl,[edi] ;Set "previous" value.
|
||||
inc edi
|
||||
jmp ??mainloop
|
||||
|
||||
; Check to see if this is a 4 bit delta code sequence.
|
||||
|
||||
??try4bit:
|
||||
inc al ;Following codes use AL+1
|
||||
cmp ah,CODE_4BIT
|
||||
jne short ??try2bit
|
||||
|
||||
; A sequence of 4bit deltas follow. AL equals the
|
||||
; number of nibble packed delta bytes to process.
|
||||
|
||||
??bit4loop:
|
||||
mov ah,[esi] ;Fetch nibble packed delta codes
|
||||
mov bl,ah
|
||||
inc [incount]
|
||||
inc esi
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
|
||||
and ebx,00001111b
|
||||
add dl,[_4bitdecode+ebx]
|
||||
pushfd
|
||||
cmp [_4bitdecode+ebx],0
|
||||
jl short ??neg1
|
||||
|
||||
popfd
|
||||
jnc short ??ok1
|
||||
mov dl,0FFh
|
||||
jmp short ??ok1
|
||||
|
||||
??neg1:
|
||||
popfd
|
||||
jc short ??ok1
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok1:
|
||||
mov dh,dl ;DH now holds new 'previous' sample.
|
||||
mov bl,ah
|
||||
shr bl,4
|
||||
add dh,[_4bitdecode+ebx]
|
||||
pushfd
|
||||
cmp [_4bitdecode+ebx],0
|
||||
jl short ??neg2
|
||||
|
||||
popfd
|
||||
jnc short ??ok2
|
||||
|
||||
mov dh,0FFh
|
||||
jmp short ??ok2
|
||||
|
||||
??neg2:
|
||||
popfd
|
||||
jc short ??ok2
|
||||
|
||||
xor dh,dh
|
||||
|
||||
??ok2:
|
||||
mov [edi],dx ;Output the two sample bytes
|
||||
sub ecx,2
|
||||
add edi,2
|
||||
|
||||
; Put the correct 'previous' sample in DL where it belongs.
|
||||
|
||||
mov dl,dh
|
||||
|
||||
; If there are more deltas to process then loop back.
|
||||
|
||||
dec al
|
||||
jnz short ??bit4loop
|
||||
jmp ??mainloop
|
||||
|
||||
; Check to see if 2 bit deltas need to be processed.
|
||||
|
||||
??try2bit:
|
||||
cmp ah,CODE_2BIT
|
||||
jne ??zerodelta
|
||||
|
||||
; A sequence of 2bit deltas follow. AL equals the number of
|
||||
; packed delta bytes to process.
|
||||
|
||||
??bit2loop:
|
||||
mov ah,[esi] ;Fetch packed delat codes
|
||||
inc [incount]
|
||||
inc esi
|
||||
|
||||
; Add first delta to 'previous' sample already in DL.
|
||||
|
||||
mov bl,ah
|
||||
and ebx,000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushfd
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg3
|
||||
|
||||
popfd
|
||||
jnc short ??ok3
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok3
|
||||
|
||||
??neg3:
|
||||
popfd
|
||||
jc short ??ok3
|
||||
xor dl,dl
|
||||
|
||||
??ok3:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,2
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushfd
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg4
|
||||
|
||||
popfd
|
||||
jnc short ??ok4
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok4
|
||||
|
||||
??neg4:
|
||||
popfd
|
||||
jc short ??ok4
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok4:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,4
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushfd
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg5
|
||||
|
||||
popfd
|
||||
jnc short ??ok5
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok5
|
||||
|
||||
??neg5:
|
||||
popfd
|
||||
jc short ??ok5
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok5:
|
||||
mov dh,dl
|
||||
ror edx,8
|
||||
mov bl,ah
|
||||
shr ebx,6
|
||||
and bl,00000011b
|
||||
add dl,[_2bitdecode+ebx]
|
||||
pushfd
|
||||
cmp [_2bitdecode+ebx],0
|
||||
jl short ??neg6
|
||||
|
||||
popfd
|
||||
jnc short ??ok6
|
||||
|
||||
mov dl,0FFh
|
||||
jmp short ??ok6
|
||||
|
||||
??neg6:
|
||||
popfd
|
||||
jc short ??ok6
|
||||
|
||||
xor dl,dl
|
||||
|
||||
??ok6:
|
||||
ror edx,8
|
||||
mov [edi],edx ;Output two sample bytes
|
||||
sub ecx,4
|
||||
add edi,4
|
||||
|
||||
; Put the correct 'previous' sample in DL where it belongs.
|
||||
|
||||
rol edx,8
|
||||
|
||||
; If there are more deltas to process then loop back.
|
||||
|
||||
dec al
|
||||
jnz ??bit2loop
|
||||
jmp ??mainloop
|
||||
|
||||
; There is a run of zero deltas. Zero deltas merely duplicate
|
||||
; the 'previous' sample the requested number of times.
|
||||
|
||||
??zerodelta:
|
||||
xor ebx,ebx
|
||||
mov bl,al
|
||||
mov al,dl
|
||||
sub ecx,ebx
|
||||
xchg ecx,ebx
|
||||
rep stosb
|
||||
mov ecx,ebx
|
||||
jmp ??mainloop
|
||||
|
||||
??fini:
|
||||
popfd
|
||||
mov eax,[incount]
|
||||
ret
|
||||
|
||||
ENDP Decompress_Frame
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
END
|
||||
462
WIN32LIB/SRCDEBUG/BITBLIT.ASM
Normal file
462
WIN32LIB/SRCDEBUG/BITBLIT.ASM
Normal file
@@ -0,0 +1,462 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Library *
|
||||
;* *
|
||||
;* File Name : BITBLIT.ASM *
|
||||
;* *
|
||||
;* Programmer : Julio R. Jerez *
|
||||
;* *
|
||||
;* Start Date : Feb 6, 1995 *
|
||||
;* *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
CODESEG
|
||||
|
||||
PROC Linear_Blit_To_Linear C near
|
||||
USES ebx,ecx,edx,esi,edi
|
||||
|
||||
;*===================================================================
|
||||
;* define the arguements that our function takes.
|
||||
;*===================================================================
|
||||
ARG this_object :DWORD ; this is a member function
|
||||
ARG dest :DWORD ; what are we blitting to
|
||||
ARG x_pixel :DWORD ; x pixel position in source
|
||||
ARG y_pixel :DWORD ; y pixel position in source
|
||||
ARG dest_x0 :dword
|
||||
ARG dest_y0 :dword
|
||||
ARG pixel_width :DWORD ; width of rectangle to blit
|
||||
ARG pixel_height:DWORD ; height of rectangle to blit
|
||||
ARG trans :DWORD ; do we deal with transparents?
|
||||
|
||||
;*===================================================================
|
||||
; Define some locals so that we can handle things quickly
|
||||
;*===================================================================
|
||||
LOCAL x1_pixel :dword
|
||||
LOCAL y1_pixel :dword
|
||||
LOCAL dest_x1 : dword
|
||||
LOCAL dest_y1 : dword
|
||||
LOCAL scr_ajust_width:DWORD
|
||||
LOCAL dest_ajust_width:DWORD
|
||||
LOCAL source_area : dword
|
||||
LOCAL dest_area : dword
|
||||
|
||||
;This Clipping algorithm is a derivation of the very well known
|
||||
;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency
|
||||
;it is probably the most commontly implemented algorithm both in software
|
||||
;and hardware for clipping lines, rectangles, and convex polygons against
|
||||
;a rectagular clipping window. For reference see
|
||||
;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes
|
||||
; pages 113 to 177".
|
||||
; Briefly consist in computing the Sutherland code for both end point of
|
||||
; the rectangle to find out if the rectangle is:
|
||||
; - trivially accepted (no further clipping test, display rectangle)
|
||||
; - trivially rejected (return with no action)
|
||||
; - retangle must be iteratively clipped again edges of the clipping window
|
||||
; and the remaining retangle is display.
|
||||
|
||||
; Clip Source Rectangle against source Window boundaries.
|
||||
mov esi,[this_object] ; get ptr to src
|
||||
xor ecx,ecx ; Set sutherland code to zero
|
||||
xor edx,edx ; Set sutherland code to zero
|
||||
|
||||
; compute the difference in the X axis and get the bit signs into ecx , edx
|
||||
mov edi,[(GraphicViewPort esi).GVPWidth] ; get width into register
|
||||
mov ebx,[x_pixel] ; Get first end point x_pixel into register
|
||||
mov eax,[x_pixel] ; Get second end point x_pixel into register
|
||||
add ebx,[pixel_width] ; second point x1_pixel = x + width
|
||||
shld ecx, eax,1 ; the sign bit of x_pixel is sutherland code0 bit4
|
||||
mov [x1_pixel],ebx ; save second for future use
|
||||
inc edi ; move the right edge by one unit
|
||||
shld edx,ebx,1 ; the sign bit of x1_pixel is sutherland code0 bit4
|
||||
sub eax,edi ; compute the difference x0_pixel - width
|
||||
sub ebx,edi ; compute the difference x1_pixel - width
|
||||
shld ecx,eax,1 ; the sign bit of the difference is sutherland code0 bit3
|
||||
shld edx,ebx,1 ; the sign bit of the difference is sutherland code0 bit3
|
||||
|
||||
; the following code is just a repeticion of the above code
|
||||
; in the Y axis.
|
||||
mov edi,[(GraphicViewPort esi).GVPHeight] ; get height into register
|
||||
mov ebx,[y_pixel]
|
||||
mov eax,[y_pixel]
|
||||
add ebx,[pixel_height]
|
||||
shld ecx,eax,1
|
||||
mov [y1_pixel ],ebx
|
||||
inc edi
|
||||
shld edx,ebx,1
|
||||
sub eax,edi
|
||||
sub ebx,edi
|
||||
shld ecx,eax,1
|
||||
shld edx,ebx,1
|
||||
|
||||
; Here we have the to Sutherland code into cl and dl
|
||||
xor cl,5 ; bit 2 and 0 are complented, reverse then
|
||||
xor dl,5 ; bit 2 and 0 are complented, reverse then
|
||||
mov al,cl ; save code1 in case we have to clip iteratively
|
||||
test dl,cl ; if any bit in code0 and its counter bit
|
||||
jnz ??real_out ; in code1 is set then the rectangle in outside
|
||||
or al,dl ; if all bit of code0 the counter bit in
|
||||
jz ??clip_against_dest ; in code1 is set to zero, then all
|
||||
; end points of the rectangle are
|
||||
; inside the clipping window
|
||||
|
||||
; if we are here the polygon have to be clip iteratively
|
||||
test cl,1000b ; if bit 4 in code0 is set then
|
||||
jz ??scr_left_ok ; x_pixel is smaller than zero
|
||||
mov [x_pixel],0 ; set x_pixel to cero.
|
||||
|
||||
??scr_left_ok:
|
||||
test cl,0010b ; if bit 2 in code0 is set then
|
||||
jz ??scr_bottom_ok ; y_pixel is smaller than zero
|
||||
mov [ y_pixel ],0 ; set y_pixel to cero.
|
||||
|
||||
??scr_bottom_ok:
|
||||
test dl,0100b ; if bit 3 in code1 is set then
|
||||
jz ??scr_right_ok ; x1_pixel is greater than the width
|
||||
mov eax,[(GraphicViewPort esi).GVPWidth] ; get width into register
|
||||
mov [ x1_pixel ],eax ; set x1_pixel to width.
|
||||
??scr_right_ok:
|
||||
test dl,0001b ; if bit 0 in code1 is set then
|
||||
jz ??clip_against_dest ; y1_pixel is greater than the width
|
||||
mov eax,[(GraphicViewPort esi).GVPHeight] ; get height into register
|
||||
mov [ y1_pixel ],eax ; set y1_pixel to height.
|
||||
|
||||
; Clip Source Rectangle against destination Window boundaries.
|
||||
??clip_against_dest:
|
||||
|
||||
; build the destination rectangle before clipping
|
||||
; dest_x1 = dest_x0 + ( x1_pixel - x_pixel )
|
||||
; dest_y1 = dest_y0 + ( y1_pixel - y_pixel )
|
||||
mov eax,[dest_x0] ; get dest_x0 into eax
|
||||
mov ebx,[dest_y0] ; get dest_y0 into ebx
|
||||
sub eax,[x_pixel] ; subtract x_pixel from eax
|
||||
sub ebx,[y_pixel] ; subtract y_pixel from ebx
|
||||
add eax,[x1_pixel] ; add x1_pixel to eax
|
||||
add ebx,[y1_pixel] ; add y1_pixel to ebx
|
||||
mov [dest_x1],eax ; save eax into dest_x1
|
||||
mov [dest_y1],ebx ; save eax into dest_y1
|
||||
|
||||
|
||||
; The followin code is a repeticion of the Sutherland clipping
|
||||
; descrived above.
|
||||
mov esi,[dest] ; get ptr to src
|
||||
xor ecx,ecx
|
||||
xor edx,edx
|
||||
mov edi,[(GraphicViewPort esi).GVPWidth] ; get width into register
|
||||
mov eax,[dest_x0]
|
||||
mov ebx,[dest_x1]
|
||||
shld ecx,eax,1
|
||||
inc edi
|
||||
shld edx,ebx,1
|
||||
sub eax,edi
|
||||
sub ebx,edi
|
||||
shld ecx,eax,1
|
||||
shld edx,ebx,1
|
||||
|
||||
mov edi,[( GraphicViewPort esi) . GVPHeight ] ; get height into register
|
||||
mov eax,[dest_y0]
|
||||
mov ebx,[dest_y1]
|
||||
shld ecx,eax,1
|
||||
inc edi
|
||||
shld edx,ebx,1
|
||||
sub eax,edi
|
||||
sub ebx,edi
|
||||
shld ecx,eax,1
|
||||
shld edx,ebx,1
|
||||
|
||||
xor cl,5
|
||||
xor dl,5
|
||||
mov al,cl
|
||||
test dl,cl
|
||||
jnz ??real_out
|
||||
or al,dl
|
||||
jz ??do_blit
|
||||
|
||||
test cl,1000b
|
||||
jz ??dest_left_ok
|
||||
mov eax,[ dest_x0 ]
|
||||
mov [ dest_x0 ],0
|
||||
sub [ x_pixel ],eax
|
||||
|
||||
??dest_left_ok:
|
||||
test cl,0010b
|
||||
jz ??dest_bottom_ok
|
||||
mov eax,[ dest_y0 ]
|
||||
mov [ dest_y0 ],0
|
||||
sub [ y_pixel ],eax
|
||||
|
||||
|
||||
??dest_bottom_ok:
|
||||
test dl,0100b
|
||||
jz ??dest_right_ok
|
||||
mov ebx,[ (GraphicViewPort esi) . GVPWidth ] ; get width into register
|
||||
mov eax,[ dest_x1 ]
|
||||
mov [ dest_x1 ],ebx
|
||||
sub eax,ebx
|
||||
sub [ x1_pixel ],eax
|
||||
|
||||
??dest_right_ok:
|
||||
test dl,0001b
|
||||
jz ??do_blit
|
||||
mov ebx,[ (GraphicViewPort esi) . GVPHeight ] ; get width into register
|
||||
mov eax,[ dest_y1 ]
|
||||
mov [ dest_y1 ],ebx
|
||||
sub eax,ebx
|
||||
sub [ y1_pixel ],eax
|
||||
|
||||
|
||||
; Here is where we do the actual blit
|
||||
??do_blit:
|
||||
cld
|
||||
mov ebx,[this_object]
|
||||
mov esi,[(GraphicViewPort ebx).GVPOffset]
|
||||
mov eax,[(GraphicViewPort ebx).GVPXAdd]
|
||||
add eax,[(GraphicViewPort ebx).GVPWidth]
|
||||
add eax,[(GraphicViewPort ebx).GVPPitch]
|
||||
mov ecx,eax
|
||||
mul [y_pixel]
|
||||
add esi,[x_pixel]
|
||||
mov [source_area],ecx
|
||||
add esi,eax
|
||||
|
||||
add ecx,[x_pixel ]
|
||||
sub ecx,[x1_pixel ]
|
||||
mov [scr_ajust_width ],ecx
|
||||
|
||||
mov ebx,[dest]
|
||||
mov edi,[(GraphicViewPort ebx).GVPOffset]
|
||||
mov eax,[(GraphicViewPort ebx).GVPXAdd]
|
||||
add eax,[(GraphicViewPort ebx).GVPWidth]
|
||||
add eax,[(GraphicViewPort ebx).GVPPitch]
|
||||
mov ecx,eax
|
||||
mul [ dest_y0 ]
|
||||
add edi,[ dest_x0 ]
|
||||
mov [ dest_area ],ecx
|
||||
add edi,eax
|
||||
|
||||
mov eax,[ dest_x1 ]
|
||||
sub eax,[ dest_x0 ]
|
||||
jle ??real_out
|
||||
sub ecx,eax
|
||||
mov [ dest_ajust_width ],ecx
|
||||
|
||||
mov edx,[ dest_y1 ]
|
||||
sub edx,[ dest_y0 ]
|
||||
jle ??real_out
|
||||
|
||||
cmp esi,edi
|
||||
jz ??real_out
|
||||
jl ??backupward_blit
|
||||
|
||||
; ********************************************************************
|
||||
; Forward bitblit
|
||||
|
||||
test [ trans ],1
|
||||
jnz ??forward_Blit_trans
|
||||
|
||||
|
||||
; the inner loop is so efficient that
|
||||
; the optimal consept no longer apply because
|
||||
; the optimal byte have to by a number greather than 9 bytes
|
||||
cmp eax,10
|
||||
jl ??forward_loop_bytes
|
||||
|
||||
??forward_loop_dword:
|
||||
mov ecx,edi
|
||||
mov ebx,eax
|
||||
neg ecx
|
||||
and ecx,3
|
||||
sub ebx,ecx
|
||||
rep movsb
|
||||
mov ecx,ebx
|
||||
shr ecx,2
|
||||
rep movsd
|
||||
mov ecx,ebx
|
||||
and ecx,3
|
||||
rep movsb
|
||||
add esi,[ scr_ajust_width ]
|
||||
add edi,[ dest_ajust_width ]
|
||||
dec edx
|
||||
jnz ??forward_loop_dword
|
||||
ret
|
||||
|
||||
??forward_loop_bytes:
|
||||
mov ecx,eax
|
||||
rep movsb
|
||||
add esi,[ scr_ajust_width ]
|
||||
add edi,[ dest_ajust_width ]
|
||||
dec edx
|
||||
jnz ??forward_loop_bytes
|
||||
ret
|
||||
|
||||
??forward_Blit_trans:
|
||||
mov ecx,eax
|
||||
and ecx,01fh
|
||||
lea ecx,[ ecx + ecx * 4 ]
|
||||
neg ecx
|
||||
shr eax,5
|
||||
lea ecx,[ ??transp_reference + ecx * 2 ]
|
||||
mov [ y1_pixel ],ecx
|
||||
|
||||
??forward_loop_trans:
|
||||
mov ecx,eax
|
||||
jmp [ y1_pixel ]
|
||||
??forward_trans_line:
|
||||
REPT 32
|
||||
local transp_pixel
|
||||
mov bl,[ esi ]
|
||||
test bl,bl
|
||||
jz transp_pixel
|
||||
mov [ edi ],bl
|
||||
transp_pixel:
|
||||
inc esi
|
||||
inc edi
|
||||
ENDM
|
||||
??transp_reference:
|
||||
dec ecx
|
||||
jge ??forward_trans_line
|
||||
add esi,[ scr_ajust_width ]
|
||||
add edi,[ dest_ajust_width ]
|
||||
dec edx
|
||||
jnz ??forward_loop_trans
|
||||
ret
|
||||
|
||||
|
||||
; ************************************************************************
|
||||
; backward bitblit
|
||||
|
||||
??backupward_blit:
|
||||
|
||||
mov ebx,[ source_area ]
|
||||
dec edx
|
||||
add esi,eax
|
||||
imul ebx,edx
|
||||
std
|
||||
lea esi,[ esi + ebx - 1 ]
|
||||
|
||||
mov ebx,[ dest_area ]
|
||||
add edi,eax
|
||||
imul ebx,edx
|
||||
lea edi,[ edi + ebx - 1]
|
||||
|
||||
test [ trans ],1
|
||||
jnz ??backward_Blit_trans
|
||||
|
||||
cmp eax,15
|
||||
jl ??backward_loop_bytes
|
||||
|
||||
??backward_loop_dword:
|
||||
push edi
|
||||
push esi
|
||||
lea ecx,[edi+1]
|
||||
mov ebx,eax
|
||||
and ecx,3 ; Get non aligned bytes.
|
||||
sub ebx,ecx ; remove that from the total size to be copied later.
|
||||
rep movsb ; do the copy.
|
||||
sub esi,3
|
||||
mov ecx,ebx ; Get number of bytes left.
|
||||
sub edi,3
|
||||
shr ecx,2 ; Do 4 bytes at a time.
|
||||
rep movsd ; do the dword copy.
|
||||
mov ecx,ebx
|
||||
add esi,3
|
||||
add edi,3
|
||||
and ecx,03h
|
||||
rep movsb ; finnish the remaining bytes.
|
||||
pop esi
|
||||
pop edi
|
||||
sub esi,[ source_area ]
|
||||
sub edi,[ dest_area ]
|
||||
dec edx
|
||||
jge ??backward_loop_dword
|
||||
cld
|
||||
ret
|
||||
|
||||
??backward_loop_bytes:
|
||||
push edi
|
||||
mov ecx,eax ; remove that from the total size to be copied later.
|
||||
push esi
|
||||
rep movsb ; do the copy.
|
||||
pop esi
|
||||
pop edi
|
||||
sub esi,[ source_area ]
|
||||
sub edi,[ dest_area ]
|
||||
dec edx
|
||||
jge ??backward_loop_bytes
|
||||
cld
|
||||
ret
|
||||
|
||||
??backward_Blit_trans:
|
||||
mov ecx,eax
|
||||
and ecx,01fh
|
||||
lea ecx,[ ecx + ecx * 4 ]
|
||||
neg ecx
|
||||
shr eax,5
|
||||
lea ecx,[ ??back_transp_reference + ecx * 2 ]
|
||||
mov [ y1_pixel ],ecx
|
||||
|
||||
??backward_loop_trans:
|
||||
mov ecx,eax
|
||||
push edi
|
||||
push esi
|
||||
jmp [ y1_pixel ]
|
||||
??backward_trans_line:
|
||||
REPT 32
|
||||
local transp_pixel
|
||||
mov bl,[ esi ]
|
||||
test bl,bl
|
||||
jz transp_pixel
|
||||
mov [ edi ],bl
|
||||
transp_pixel:
|
||||
dec esi
|
||||
dec edi
|
||||
ENDM
|
||||
??back_transp_reference:
|
||||
dec ecx
|
||||
jge ??backward_trans_line
|
||||
pop esi
|
||||
pop edi
|
||||
sub esi,[ source_area ]
|
||||
sub edi,[ dest_area ]
|
||||
dec edx
|
||||
jge ??backward_loop_trans
|
||||
cld
|
||||
ret
|
||||
|
||||
??real_out:
|
||||
ret
|
||||
ENDP Linear_Blit_To_Linear
|
||||
|
||||
|
||||
|
||||
END
|
||||
131
WIN32LIB/SRCDEBUG/BUFFER.CPP
Normal file
131
WIN32LIB/SRCDEBUG/BUFFER.CPP
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 Bit Library *
|
||||
* *
|
||||
* File Name : BUFFER.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : May 18, 1994 *
|
||||
* *
|
||||
* Last Update : June 1, 1994 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* BC::BufferClass -- The default (void) constructor for a buffer class *
|
||||
* BC::~BufferClass -- The destructor for the buffer class *
|
||||
* BC::BufferClass -- The standard constructor for a buffer class *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef BUFFER_H
|
||||
#include "buffer.h"
|
||||
#endif
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
/***************************************************************************
|
||||
* BC::BufferClass -- The standard constructor for a buffer class *
|
||||
* *
|
||||
* INPUT: VOID * buffer to which should be included in buffer class *
|
||||
* LONG size of the buffer which we included *
|
||||
* *
|
||||
* OUTPUT: NONE *
|
||||
* *
|
||||
* WARNINGS: If the buffer passed to this function is equal to NULL, *
|
||||
* the buffer will be allocated using new. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/01/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
BufferClass::BufferClass(VOID *buffer, LONG size)
|
||||
{
|
||||
Size = size; // find size of physical buffer
|
||||
|
||||
if (buffer) { // if buffer is specified
|
||||
Buffer = (BYTE *)buffer; // point to it and mark
|
||||
Allocated = FALSE; // it as user allocated
|
||||
} else {
|
||||
Buffer = new BYTE[Size]; // otherwise allocate it and
|
||||
Allocated = TRUE; // mark it system alloced
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* BC::BufferClass -- constructor for BufferClass with size only *
|
||||
* *
|
||||
* INPUT: LONG the size of the buffer that needs to be allocated *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/01/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
BufferClass::BufferClass(LONG size)
|
||||
{
|
||||
Size = size;
|
||||
Buffer = new BYTE[Size]; // otherwise allocate it and
|
||||
Allocated = TRUE; // mark it system alloced
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* BC::BufferClass -- The default (void) constructor for a buffer class *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* NOTES: The primary function of this class is to be called by a *
|
||||
* derived class which will fill in the values after the *
|
||||
* fact. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/01/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
BufferClass::BufferClass(VOID)
|
||||
{
|
||||
Buffer = NULL;
|
||||
Size = 0;
|
||||
Allocated = FALSE;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* BC::~BUFFERCLASS -- The destructor for the buffer class *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/01/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
BufferClass::~BufferClass(VOID)
|
||||
{
|
||||
if (Allocated) {
|
||||
delete[] Buffer;
|
||||
}
|
||||
}
|
||||
83
WIN32LIB/SRCDEBUG/BUFFGLBL.CPP
Normal file
83
WIN32LIB/SRCDEBUG/BUFFGLBL.CPP
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : BUFFGLBL.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : January 10, 1995 *
|
||||
* *
|
||||
* Last Update : January 10, 1995 [PWG] *
|
||||
* *
|
||||
* This module holds the global fixup tables for the MCGA buffer class. *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#include "gbuffer.h"
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
/*=========================================================================*/
|
||||
/* Globals required by GraphicBufferClass for function pointers. These */
|
||||
/* pointers will be set to the proper function when set mode is called. */
|
||||
/*=========================================================================*/
|
||||
BOOL (*GVPC_Blit_to_VVPC_Func)(void *, void *, int, int, int, int, int, int, BOOL);
|
||||
BOOL (*GVPC_Scale_To_VVPC)( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *);
|
||||
|
||||
#ifdef not_any_more_it_doesnt
|
||||
/*=========================================================================*/
|
||||
/* Globals required by VideoBufferClass for function pointers. These */
|
||||
/* pointers will be set to the proper function when set mode is called. */
|
||||
/*=========================================================================*/
|
||||
void (*VVPC_Clear_Func)(void *, unsigned char);
|
||||
long (*VVPC_To_Buffer_Func)(void *,int x, int y, int w, int h, void *buff, long size);
|
||||
void (*VVPC_Put_Pixel_Func)(void *,int x, int y, unsigned char color);
|
||||
int (*VVPC_Get_Pixel_Func)(void *, int x, int y);
|
||||
long (*VVPC_Buffer_To_Page)(int x, int y, int w, int h, void *Buffer, void *view);
|
||||
BOOL (*VVPC_Blit_to_GVPC_Func)(void *, void *, int, int, int, int, int, int, BOOL);
|
||||
BOOL (*VVPC_Blit_to_VVPC_Func)(void *, void *, int, int, int, int, int, int, BOOL);
|
||||
BOOL (*VVPC_Scale_To_GVPC)( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *);
|
||||
BOOL (*VVPC_Scale_To_VVPC)( void *, void *, int, int, int, int, int, int, int, int, BOOL, char *);
|
||||
LONG (*VVPC_Print_Func)( void *, const char *, int, int, int, int);
|
||||
void (*VVPC_Draw_Stamp)(void *, void *, int, int, int, void *);
|
||||
long (*VVPC_Size_Of_Region)(void *, int, int);
|
||||
|
||||
#endif //not_any_more_it_doesnt
|
||||
|
||||
/*=========================================================================*/
|
||||
/* We need to keep a pointer to the logic page hanging around somewhere */
|
||||
/*=========================================================================*/
|
||||
GraphicViewPortClass *LogicPage;
|
||||
|
||||
BOOL IconCacheAllowed = TRUE;
|
||||
|
||||
/*
|
||||
** Pointer to a function we will call if we detect loss of focus
|
||||
*/
|
||||
void (*Gbuffer_Focus_Loss_Function)(void) = NULL;
|
||||
604
WIN32LIB/SRCDEBUG/CCFILE.CPP
Normal file
604
WIN32LIB/SRCDEBUG/CCFILE.CPP
Normal file
@@ -0,0 +1,604 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: F:\projects\c&c0\vcs\code\ccfile.cpv 2.20 27 Sep 1995 12:45:16 JOE_BOSTIC $ */
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Command & Conquer *
|
||||
* *
|
||||
* File Name : CCFILE.CPP *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : August 8, 1994 *
|
||||
* *
|
||||
* Last Update : March 20, 1995 [JLB] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* CCFileClass::CCFileClass -- Default constructor for file object. *
|
||||
* CCFileClass::CCFileClass -- Filename based constructor for C&C file. *
|
||||
* CCFileClass::Close -- Closes the file. *
|
||||
* CCFileClass::Is_Available -- Checks for existence of file on disk or in mixfile. *
|
||||
* CCFileClass::Is_Open -- Determines if the file is open. *
|
||||
* CCFileClass::Open -- Opens a file from either the mixfile system or the rawfile system. *
|
||||
* CCFileClass::Read -- Reads data from the file. *
|
||||
* CCFileClass::Seek -- Moves the current file pointer in the file. *
|
||||
* CCFileClass::Size -- Determines the size of the file. *
|
||||
* CCFileClass::Write -- Writes data to the file (non mixfile files only). *
|
||||
* CCFileClass::Error -- Handles displaying a file error message. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "function.h"
|
||||
#include <direct.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <dos.h>
|
||||
#include <errno.h>
|
||||
#include <share.h>
|
||||
#include "ccfile.h"
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Error -- Handles displaying a file error message. *
|
||||
* *
|
||||
* Display an error message as indicated. If it is allowed to retry, then pressing a key *
|
||||
* will return from this function. Otherwise, it will exit the program with "exit()". *
|
||||
* *
|
||||
* INPUT: error -- The error number (same as the DOSERR.H error numbers). *
|
||||
* *
|
||||
* canretry -- Can this routine exit normally so that retrying can occur? If this is *
|
||||
* false, then the program WILL exit in this routine. *
|
||||
* *
|
||||
* filename -- Optional filename to report with this error. If no filename is *
|
||||
* supplied, then no filename is listed in the error message. *
|
||||
* *
|
||||
* OUTPUT: none, but this routine might not return at all if the "canretry" parameter is *
|
||||
* false or the player pressed ESC. *
|
||||
* *
|
||||
* WARNINGS: This routine may not return at all. It handles being in text mode as well as *
|
||||
* if in a graphic mode. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void CCFileClass::Error(int , int , char const * )
|
||||
{
|
||||
if (!Force_CD_Available(RequiredCD)) {
|
||||
Prog_End();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::CCFileClass -- Filename based constructor for C&C file. *
|
||||
* *
|
||||
* Use this constructor for a file when the filename is known at construction time. *
|
||||
* *
|
||||
* INPUT: filename -- Pointer to the filename to use for this file object. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: The filename pointer is presumed to be inviolate throughout the duration of *
|
||||
* the file object. If this is not guaranteed, then use the default constructor *
|
||||
* and then set the name manually. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/20/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
CCFileClass::CCFileClass(char const *filename)
|
||||
{
|
||||
Set_Name(filename);
|
||||
FromDisk = false;
|
||||
Pointer = 0;
|
||||
Position = 0;
|
||||
Length = 0;
|
||||
Start = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::CCFileClass -- Default constructor for file object. *
|
||||
* *
|
||||
* This is the default constructor for a C&C file object. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/20/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
CCFileClass::CCFileClass(void) : CDFileClass()
|
||||
{
|
||||
FromDisk = false;
|
||||
Pointer = 0;
|
||||
Position = 0;
|
||||
Length = 0;
|
||||
Start = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Write -- Writes data to the file (non mixfile files only). *
|
||||
* *
|
||||
* This routine will write data to the file, but NOT to a file that is part of a mixfile. *
|
||||
* *
|
||||
* INPUT: buffer -- Pointer to the buffer that holds the data to be written. *
|
||||
* *
|
||||
* size -- The number of bytes to write. *
|
||||
* *
|
||||
* OUTPUT: Returns the number of bytes actually written. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
long CCFileClass::Write(void const *buffer, long size)
|
||||
{
|
||||
|
||||
/*
|
||||
** If this is part of a mixfile, then writing is not allowed. Error out with a fatal
|
||||
** message.
|
||||
*/
|
||||
if (Pointer || FromDisk) {
|
||||
Error(EACCES, false, File_Name());
|
||||
}
|
||||
|
||||
return(CDFileClass::Write(buffer, size));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Read -- Reads data from the file. *
|
||||
* *
|
||||
* This routine determines if the file is part of the mixfile system. If it is, then *
|
||||
* the file is copied from RAM if it is located there. Otherwise it is read from disk *
|
||||
* according to the correct position of the file within the parent mixfile. *
|
||||
* *
|
||||
* INPUT: buffer -- Pointer to the buffer to place the read data. *
|
||||
* *
|
||||
* size -- The number of bytes to read. *
|
||||
* *
|
||||
* OUTPUT: Returns the actual number of bytes read (this could be less than requested). *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
long CCFileClass::Read(void *buffer, long size)
|
||||
{
|
||||
int opened = false;
|
||||
|
||||
if (!Is_Open()) {
|
||||
if (Open()) {
|
||||
opened = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If the file is part of a loaded mixfile, then a mere copy is
|
||||
** all that is required for the read.
|
||||
*/
|
||||
if (Pointer) {
|
||||
long maximum = Length - Position;
|
||||
|
||||
size = MIN(maximum, size);
|
||||
if (size) {
|
||||
Mem_Copy(Add_Long_To_Pointer(Pointer, Position), buffer, size);
|
||||
Position += size;
|
||||
}
|
||||
if (opened) Close();
|
||||
return(size);
|
||||
}
|
||||
|
||||
/*
|
||||
** If the file is part of a mixfile, but the mixfile is located
|
||||
** on disk, then a special read operation is necessary.
|
||||
*/
|
||||
if (FromDisk) {
|
||||
long maximum = Length - Position;
|
||||
|
||||
size = MIN(maximum, size);
|
||||
if (size > 0) {
|
||||
CDFileClass::Seek(Start + Position, SEEK_SET);
|
||||
size = CDFileClass::Read(buffer, size);
|
||||
Position += size;
|
||||
}
|
||||
if (opened) Close();
|
||||
return(size);
|
||||
}
|
||||
|
||||
long s = CDFileClass::Read(buffer, size);
|
||||
if (opened) Close();
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Seek -- Moves the current file pointer in the file. *
|
||||
* *
|
||||
* This routine will change the current file pointer to the position specified. It follows *
|
||||
* the same rules the a normal Seek() does, but if the file is part of the mixfile system, *
|
||||
* then only the position value needs to be updated. *
|
||||
* *
|
||||
* INPUT: pos -- The position to move the file to relative to the position indicated *
|
||||
* by the "dir" parameter. *
|
||||
* *
|
||||
* dir -- The direction to affect the position change against. This can be *
|
||||
* either SEEK_CUR, SEEK_END, or SEEK_SET. *
|
||||
* *
|
||||
* OUTPUT: Returns with the position of the new location. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
long CCFileClass::Seek(long pos, int dir)
|
||||
{
|
||||
if (Pointer || FromDisk) {
|
||||
switch (dir) {
|
||||
case SEEK_END:
|
||||
Position = Length;
|
||||
break;
|
||||
|
||||
case SEEK_SET:
|
||||
Position = 0;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Position += pos;
|
||||
if (Position < 0) Position = 0;
|
||||
if (Position > Length) Position = Length;
|
||||
return(Position);
|
||||
}
|
||||
return(CDFileClass::Seek(pos, dir));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Size -- Determines the size of the file. *
|
||||
* *
|
||||
* If the file is part of the mixfile system, then the size of the file is already *
|
||||
* determined and available. Otherwise, go to the low level system to find the file *
|
||||
* size. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: Returns with the size of the file in bytes. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
long CCFileClass::Size(void)
|
||||
{
|
||||
if (Pointer || FromDisk) return(Length);
|
||||
|
||||
return(CDFileClass::Size());
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Is_Available -- Checks for existence of file on disk or in mixfile. *
|
||||
* *
|
||||
* This routine will examine the mixfile system looking for the file. If the file could *
|
||||
* not be found there, then the disk is examined directly. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: bool; Is the file available for opening? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int CCFileClass::Is_Available(int )
|
||||
{
|
||||
if (MixFileClass::Offset(File_Name())) {
|
||||
return(true);
|
||||
}
|
||||
return(CDFileClass::Is_Available());
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Is_Open -- Determines if the file is open. *
|
||||
* *
|
||||
* A mixfile is open if there is a pointer to the mixfile data. In absence of this, *
|
||||
* the the file is open if the file handle is valid. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: bool; Is the file open? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int CCFileClass::Is_Open(void) const
|
||||
{
|
||||
|
||||
/*
|
||||
** If the file is part of a cached file, then return that it is opened. A closed file
|
||||
** doesn't have a valid pointer.
|
||||
*/
|
||||
if (Pointer) return(true);
|
||||
return(CDFileClass::Is_Open());
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Close -- Closes the file. *
|
||||
* *
|
||||
* If this is a mixfile file, then only the pointers need to be adjusted. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void CCFileClass::Close(void)
|
||||
{
|
||||
FromDisk = false;
|
||||
Pointer = 0;
|
||||
Position = 0; // Starts at beginning offset.
|
||||
Start = 0;
|
||||
Length = 0;
|
||||
CDFileClass::Close();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CCFileClass::Open -- Opens a file from either the mixfile system or the rawfile system. *
|
||||
* *
|
||||
* This routine will open the specified file. It examines the mixfile system to find a *
|
||||
* match. If one is found then the file is "opened" in a special cached way. Otherwise *
|
||||
* it is opened as a standard DOS file. *
|
||||
* *
|
||||
* INPUT: rights -- The access rights desired. *
|
||||
* *
|
||||
* OUTPUT: bool; Was the file opened successfully? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/08/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int CCFileClass::Open(int rights)
|
||||
{
|
||||
/*
|
||||
** Always close the file if it was open.
|
||||
*/
|
||||
Close();
|
||||
|
||||
/*
|
||||
** Perform a preliminary check to see if the specified file
|
||||
** exists on the disk. If it does, then open this file regardless
|
||||
** of whether it also exists in RAM. This is slower, but allows
|
||||
** upgrade files to work.
|
||||
*/
|
||||
if ((rights & WRITE) || CDFileClass::Is_Available()) {
|
||||
return(CDFileClass::Open(rights));
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if file is part of a mixfile and that mixfile is currently loaded
|
||||
** into RAM.
|
||||
*/
|
||||
MixFileClass *mixfile = 0;
|
||||
if (MixFileClass::Offset(File_Name(), &Pointer, &mixfile, &Start, &Length)) {
|
||||
|
||||
/*
|
||||
** If the mixfile is located on disk, then fake out the file system to read from
|
||||
** the mixfile, but think it is reading from a solitary file.
|
||||
*/
|
||||
if (!Pointer) {
|
||||
long start = Start;
|
||||
long length = Length;
|
||||
|
||||
/*
|
||||
** This is a legitimate open to the file. All access to the file through this
|
||||
** file object will be appropriately adjusted for mixfile support however. Also
|
||||
** note that the filename attached to this object is NOT the same as the file
|
||||
** attached to the file handle.
|
||||
*/
|
||||
char const * dupfile = strdup(File_Name());
|
||||
Open(mixfile->Filename, READ);
|
||||
Searching(false); // Disable multi-drive search.
|
||||
Set_Name(dupfile);
|
||||
free((void *)dupfile);
|
||||
Start = start;
|
||||
Length = length;
|
||||
FromDisk = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
** The file cannot be found in any mixfile, so it must reside as
|
||||
** an individual file on the disk. Or else it is just plain missing.
|
||||
*/
|
||||
return(CDFileClass::Open(rights));
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
** Backward compatibility section.
|
||||
*/
|
||||
//extern "C" {
|
||||
|
||||
static CCFileClass Handles[10];
|
||||
|
||||
#ifdef NEVER
|
||||
bool __cdecl Set_Search_Drives(BYTE const *)
|
||||
{
|
||||
CCFileClass::Set_Search_Path(path);
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
WORD __cdecl Open_File(BYTE const *file_name, WORD mode)
|
||||
{
|
||||
for (int index = 0; index < sizeof(Handles)/sizeof(Handles[0]); index++) {
|
||||
if (!Handles[index].Is_Open()) {
|
||||
if (Handles[index].Open(file_name, mode)) {
|
||||
return(index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
VOID __cdecl Close_File(WORD handle)
|
||||
{
|
||||
if (handle != ERROR && Handles[handle].Is_Open()) {
|
||||
Handles[handle].Close();
|
||||
}
|
||||
}
|
||||
|
||||
LONG __cdecl Read_File(WORD handle, VOID *buf, ULONG bytes)
|
||||
{
|
||||
if (handle != ERROR && Handles[handle].Is_Open()) {
|
||||
return(Handles[handle].Read(buf, bytes));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
LONG __cdecl Write_File(WORD handle, VOID const *buf, ULONG bytes)
|
||||
{
|
||||
if (handle != ERROR && Handles[handle].Is_Open()) {
|
||||
return(Handles[handle].Write(buf, bytes));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
WORD __cdecl Find_File(BYTE const *file_name)
|
||||
{
|
||||
CCFileClass file(file_name);
|
||||
return(file.Is_Available());
|
||||
}
|
||||
|
||||
#ifdef NEVER
|
||||
WORD __cdecl Delete_File(BYTE const *file_name)
|
||||
{
|
||||
return(CCFileClass(file_name).Delete());
|
||||
}
|
||||
|
||||
WORD __cdecl Create_File(BYTE const *file_name)
|
||||
{
|
||||
return(CCFileClass(file_name).Create());
|
||||
}
|
||||
|
||||
ULONG __cdecl Load_Data(BYTE const *name, VOID *ptr, ULONG size)
|
||||
{
|
||||
return(CCFileClass(name).Read(ptr, size));
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID * __cdecl Load_Alloc_Data(BYTE const *name, WORD )
|
||||
{
|
||||
CCFileClass file(name);
|
||||
|
||||
return(Load_Alloc_Data(file));
|
||||
}
|
||||
|
||||
ULONG __cdecl File_Size(WORD handle)
|
||||
{
|
||||
if (handle != ERROR && Handles[handle].Is_Open()) {
|
||||
return(Handles[handle].Size());
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef NEVER
|
||||
ULONG __cdecl Write_Data(BYTE const *name, VOID const *ptr, ULONG size)
|
||||
{
|
||||
return(CCFileClass(name).Write(ptr, size));
|
||||
}
|
||||
#endif
|
||||
|
||||
ULONG __cdecl Seek_File(WORD handle, LONG offset, WORD starting)
|
||||
{
|
||||
if (handle != ERROR && Handles[handle].Is_Open()) {
|
||||
return(Handles[handle].Seek(offset, starting));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef NEVER
|
||||
bool __cdecl Multi_Drive_Search(bool on)
|
||||
{
|
||||
// return(CCFileClass::Multi_Drive_Search(on));
|
||||
return(on);
|
||||
}
|
||||
|
||||
VOID __cdecl WWDOS_Init(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
VOID __cdecl WWDOS_Shutdown(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
WORD __cdecl Find_Disk_Number(BYTE const *)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//ULONG cdecl Load_Uncompress(BYTE const *file, BuffType uncomp_buff, BuffType dest_buff, VOID *reserved_data)
|
||||
//{
|
||||
// return(Load_Uncompress(CCFileClass(file), uncomp_buff, dest_buff, reserved_data));
|
||||
// return(CCFileClass(file).Load_Uncompress(uncomp_buff, dest_buff, reserved_data));
|
||||
//}
|
||||
extern "C" {
|
||||
int MaxDevice;
|
||||
int DefaultDrive;
|
||||
char CallingDOSInt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Unfragment_File_Cache(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
130
WIN32LIB/SRCDEBUG/CLEAR.ASM
Normal file
130
WIN32LIB/SRCDEBUG/CLEAR.ASM
Normal file
@@ -0,0 +1,130 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Clear the Full Graphics Buffer *
|
||||
;* *
|
||||
;* File Name : CLEAR.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil Gorrow *
|
||||
;* *
|
||||
;* Start Date : June 7, 1994 *
|
||||
;* *
|
||||
;* Last Update : August 23, 1994 [SKB] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* GVPC::Clear -- Clears a virtual viewport instance *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* VVPC::CLEAR -- Clears a virtual viewport instance *
|
||||
;* *
|
||||
;* INPUT: UBYTE the color (optional) to clear the view port to *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* NOTE: This function is optimized to handle viewport with no XAdd *
|
||||
;* value. It also handles DWORD aligning the destination *
|
||||
;* when speed can be gained by doing it. *
|
||||
;* HISTORY: *
|
||||
;* 06/07/1994 PWG : Created. *
|
||||
;* 08/23/1994 SKB : Clear the direction flag to always go forward. *
|
||||
;*=========================================================================*
|
||||
PROC Buffer_Clear C near
|
||||
USES eax,ebx,ecx,edx,esi,edi
|
||||
|
||||
ARG this_object:DWORD ; this is a member function
|
||||
ARG color:BYTE ; what color should we clear to
|
||||
|
||||
cld ; always go forward
|
||||
|
||||
mov ebx,[this_object] ; get a pointer to viewport
|
||||
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
|
||||
mov edx,[(GraphicViewPort ebx).GVPHeight] ; ecx = height of viewport
|
||||
mov esi,[(GraphicViewPort ebx).GVPWidth] ; edx = width of viewport
|
||||
push [dword (GraphicViewPort ebx).GVPPitch] ; extra pitch of direct draw surface
|
||||
mov ebx,[(GraphicViewPort ebx).GVPXAdd] ; esi = add for each line
|
||||
add ebx,[esp] ; Yes, I know its nasty but
|
||||
add esp,4 ; it works!
|
||||
|
||||
;*===================================================================
|
||||
; Convert the color byte to a DWORD for fast storing
|
||||
;*===================================================================
|
||||
mov al,[color] ; get color to clear to
|
||||
mov ah,al ; extend across WORD
|
||||
mov ecx,eax ; extend across DWORD in
|
||||
shl eax,16 ; several steps
|
||||
mov ax,cx
|
||||
|
||||
;*===================================================================
|
||||
; Find out if we should bother to align the row.
|
||||
;*===================================================================
|
||||
|
||||
cmp esi , OPTIMAL_BYTE_COPY ; is it worth aligning them?
|
||||
jl ??byte_by_byte ; if not then skip
|
||||
|
||||
;*===================================================================
|
||||
; Figure out the alignment offset if there is any
|
||||
;*===================================================================
|
||||
push ebx
|
||||
??dword_aligned_loop:
|
||||
mov ecx , edi
|
||||
mov ebx , esi
|
||||
neg ecx
|
||||
and ecx , 3
|
||||
sub ebx , ecx
|
||||
rep stosb
|
||||
mov ecx , ebx
|
||||
shr ecx , 2
|
||||
rep stosd
|
||||
mov ecx , ebx
|
||||
and ecx , 3
|
||||
rep stosb
|
||||
add edi , [ esp ]
|
||||
dec edx ; decrement the height
|
||||
jnz ??dword_aligned_loop ; if more to do than do it
|
||||
pop eax
|
||||
ret
|
||||
|
||||
;*===================================================================
|
||||
; If not enough bytes to bother aligning copy each line across a byte
|
||||
; at a time.
|
||||
;*===================================================================
|
||||
??byte_by_byte:
|
||||
mov ecx,esi ; get total width in bytes
|
||||
rep stosb ; store the width
|
||||
add edi,ebx ; handle the xadd
|
||||
dec edx ; decrement the height
|
||||
jnz ??byte_by_byte ; if any left then next line
|
||||
??exit:
|
||||
ret
|
||||
ENDP Buffer_Clear
|
||||
END
|
||||
269
WIN32LIB/SRCDEBUG/CLIPRECT.ASM
Normal file
269
WIN32LIB/SRCDEBUG/CLIPRECT.ASM
Normal file
@@ -0,0 +1,269 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Support Library *
|
||||
;* *
|
||||
;* File Name : cliprect.asm *
|
||||
;* *
|
||||
;* Programmer : Julio R Jerez *
|
||||
;* *
|
||||
;* Start Date : Mar, 2 1995 *
|
||||
;* *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* int Clip_Rect ( int * x , int * y , int * dw , int * dh , *
|
||||
;* int width , int height ) ; *
|
||||
;* int Confine_Rect ( int * x , int * y , int * dw , int * dh , *
|
||||
;* int width , int height ) ; *
|
||||
;* *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Clip_Rect :NEAR
|
||||
GLOBAL C Confine_Rect :NEAR
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Clip_Rect -- clip a given rectangle against a given window *
|
||||
;* *
|
||||
;* INPUT: &x , &y , &w , &h -> Pointer to rectangle being clipped *
|
||||
;* width , height -> dimension of clipping window *
|
||||
;* *
|
||||
;* OUTPUT: a) Zero if the rectangle is totally contained by the *
|
||||
;* clipping window. *
|
||||
;* b) A negative value if the rectangle is totally outside the *
|
||||
;* the clipping window *
|
||||
;* c) A positive value if the rectangle was clipped against the *
|
||||
;* clipping window, also the values pointed by x, y, w, h will *
|
||||
;* be modified to new clipped values *
|
||||
;* *
|
||||
;* 05/03/1995 JRJ : added comment *
|
||||
;*=========================================================================*
|
||||
; int Clip_Rect (int* x, int* y, int* dw, int* dh, int width, int height); *
|
||||
|
||||
PROC Clip_Rect C near
|
||||
uses ebx,ecx,edx,esi,edi
|
||||
arg x:dword
|
||||
arg y:dword
|
||||
arg w:dword
|
||||
arg h:dword
|
||||
arg width:dword
|
||||
arg height:dword
|
||||
|
||||
;This Clipping algorithm is a derivation of the very well known
|
||||
;Cohen-Sutherland Line-Clipping test. Due to its simplicity and efficiency
|
||||
;it is probably the most commontly implemented algorithm both in software
|
||||
;and hardware for clipping lines, rectangles, and convex polygons against
|
||||
;a rectagular clipping window. For reference see
|
||||
;"COMPUTER GRAPHICS principles and practice by Foley, Vandam, Feiner, Hughes
|
||||
; pages 113 to 177".
|
||||
; Briefly consist in computing the Sutherland code for both end point of
|
||||
; the rectangle to find out if the rectangle is:
|
||||
; - trivially accepted (no further clipping test, return the oroginal data)
|
||||
; - trivially rejected (return with no action, return error code)
|
||||
; - retangle must be iteratively clipped again edges of the clipping window
|
||||
; and return the clipped rectangle
|
||||
|
||||
; get all four pointer into regisnters
|
||||
mov esi,[x] ; esi = pointer to x
|
||||
mov edi,[y] ; edi = pointer to x
|
||||
mov eax,[w] ; eax = pointer to dw
|
||||
mov ebx,[h] ; ebx = pointer to dh
|
||||
|
||||
; load the actual data into reg
|
||||
mov esi,[esi] ; esi = x0
|
||||
mov edi,[edi] ; edi = y0
|
||||
mov eax,[eax] ; eax = dw
|
||||
mov ebx,[ebx] ; ebx = dh
|
||||
|
||||
; create a wire frame of the type [x0,y0] , [x1,y1]
|
||||
add eax,esi ; eax = x1 = x0 + dw
|
||||
add ebx,edi ; ebx = y1 = y0 + dh
|
||||
|
||||
; we start we suthenland code0 and code1 set to zero
|
||||
xor ecx,ecx ; cl = sutherland boolean code0
|
||||
xor edx,edx ; dl = sutherland boolean code0
|
||||
|
||||
; now we start computing the to suthenland boolean code for x0 , x1
|
||||
shld ecx,esi,1 ; bit3 of code0 = sign bit of (x0 - 0)
|
||||
shld edx,eax,1 ; bit3 of code1 = sign bit of (x1 - 0)
|
||||
sub esi,[width] ; get the difference (x0 - (width + 1))
|
||||
sub eax,[width] ; get the difference (x1 - (width + 1))
|
||||
dec esi
|
||||
dec eax
|
||||
shld ecx,esi,1 ; bit2 of code0 = sign bit of (x0 - (width + 1))
|
||||
shld edx,eax,1 ; bit2 of code1 = sign bit of (x0 - (width + 1))
|
||||
|
||||
; now we start computing the to suthenland boolean code for y0 , y1
|
||||
shld ecx,edi,1 ; bit1 of code0 = sign bit of (y0 - 0)
|
||||
shld edx,ebx,1 ; bit1 of code1 = sign bit of (y0 - 0)
|
||||
sub edi,[height] ; get the difference (y0 - (height + 1))
|
||||
sub ebx,[height] ; get the difference (y1 - (height + 1))
|
||||
dec edi
|
||||
dec ebx
|
||||
shld ecx,edi,1 ; bit0 of code0 = sign bit of (y0 - (height + 1))
|
||||
shld edx,ebx,1 ; bit0 of code1 = sign bit of (y1 - (height + 1))
|
||||
|
||||
; Bit 2 and 0 of cl and bl are complemented
|
||||
xor cl,5 ; reverse bit2 and bit0 in code0
|
||||
xor dl,5 ; reverse bit2 and bit0 in code1
|
||||
|
||||
; now perform the rejection test
|
||||
mov eax,-1 ; set return code to false
|
||||
mov bl,cl ; save code0 for future use
|
||||
test dl,cl ; if any two pair of bit in code0 and code1 is set
|
||||
jnz ??clip_out ; then rectangle is outside the window
|
||||
|
||||
; now perform the aceptance test
|
||||
xor eax,eax ; set return code to true
|
||||
or bl,dl ; if all pair of bits in code0 and code1 are reset
|
||||
jz ??clip_out ; then rectangle is insize the window. '
|
||||
|
||||
; we need to clip the rectangle iteratively
|
||||
mov eax,-1 ; set return code to false
|
||||
test cl,1000b ; if bit3 of code0 is set then the rectangle
|
||||
jz ??left_ok ; spill out the left edge of the window
|
||||
mov edi,[x] ; edi = a pointer to x0
|
||||
mov ebx,[w] ; ebx = a pointer to dw
|
||||
mov esi,[edi] ; esi = x0
|
||||
mov [dword ptr edi],0 ; set x0 to 0 "this the left edge value"
|
||||
add [ebx],esi ; adjust dw by x0, since x0 must be negative
|
||||
|
||||
??left_ok:
|
||||
test cl,0010b ; if bit1 of code0 is set then the rectangle
|
||||
jz ??bottom_ok ; spill out the bottom edge of the window
|
||||
mov edi,[y] ; edi = a pointer to y0
|
||||
mov ebx,[h] ; ebx = a pointer to dh
|
||||
mov esi,[edi] ; esi = y0
|
||||
mov [dword ptr edi],0 ; set y0 to 0 "this the bottom edge value"
|
||||
add [ebx],esi ; adjust dh by y0, since y0 must be negative
|
||||
|
||||
??bottom_ok:
|
||||
test dl,0100b ; if bit2 of code1 is set then the rectangle
|
||||
jz ??right_ok ; spill out the right edge of the window
|
||||
mov edi,[w] ; edi = a pointer to dw
|
||||
mov esi,[x] ; esi = a pointer to x
|
||||
mov ebx,[width] ; ebx = the width of the window
|
||||
sub ebx,[esi] ; the new dw is the difference (width-x0)
|
||||
mov [edi],ebx ; adjust dw to (width - x0)
|
||||
jle ??clip_out ; if (width-x0) = 0 then the clipped retangle
|
||||
; has no width we are done
|
||||
??right_ok:
|
||||
test dl,0001b ; if bit0 of code1 is set then the rectangle
|
||||
jz ??clip_ok ; spill out the top edge of the window
|
||||
mov edi,[h] ; edi = a pointer to dh
|
||||
mov esi,[y] ; esi = a pointer to y0
|
||||
mov ebx,[height] ; ebx = the height of the window
|
||||
sub ebx,[esi] ; the new dh is the difference (height-y0)
|
||||
mov [edi],ebx ; adjust dh to (height-y0)
|
||||
jle ??clip_out ; if (width-x0) = 0 then the clipped retangle
|
||||
; has no width we are done
|
||||
??clip_ok:
|
||||
mov eax,1 ; signal the calling program that the rectangle was modify
|
||||
??clip_out:
|
||||
ret
|
||||
ENDP Clip_Rect
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* Confine_Rect -- clip a given rectangle against a given window *
|
||||
;* *
|
||||
;* INPUT: &x,&y,w,h -> Pointer to rectangle being clipped *
|
||||
;* width,height -> dimension of clipping window *
|
||||
;* *
|
||||
;* OUTPUT: a) Zero if the rectangle is totally contained by the *
|
||||
;* clipping window. *
|
||||
;* c) A positive value if the rectangle was shifted in position *
|
||||
;* to fix inside the clipping window, also the values pointed *
|
||||
;* by x, y, will adjusted to a new values *
|
||||
;* *
|
||||
;* NOTE: this function make not attempt to verify if the rectangle is *
|
||||
;* bigger than the clipping window and at the same time wrap around*
|
||||
;* it. If that is the case the result is meaningless *
|
||||
;*=========================================================================*
|
||||
; int Confine_Rect (int* x, int* y, int dw, int dh, int width, int height); *
|
||||
|
||||
PROC Confine_Rect C near
|
||||
uses ebx, esi,edi
|
||||
arg x:dword
|
||||
arg y:dword
|
||||
arg w:dword
|
||||
arg h:dword
|
||||
arg width :dword
|
||||
arg height:dword
|
||||
|
||||
xor eax,eax
|
||||
mov ebx,[x]
|
||||
mov edi,[w]
|
||||
|
||||
mov esi,[ebx]
|
||||
add edi,[ebx]
|
||||
|
||||
sub edi,[width]
|
||||
neg esi
|
||||
dec edi
|
||||
|
||||
test esi,edi
|
||||
jl ??x_axix_ok
|
||||
mov eax,1
|
||||
|
||||
test esi,esi
|
||||
jl ??shift_right
|
||||
mov [dword ptr ebx],0
|
||||
jmp ??x_axix_ok
|
||||
??shift_right:
|
||||
inc edi
|
||||
sub [ebx],edi
|
||||
??x_axix_ok:
|
||||
mov ebx,[y]
|
||||
mov edi,[h]
|
||||
|
||||
mov esi,[ebx]
|
||||
add edi,[ebx]
|
||||
|
||||
sub edi,[height]
|
||||
neg esi
|
||||
dec edi
|
||||
|
||||
test esi,edi
|
||||
jl ??confi_out
|
||||
mov eax,1
|
||||
|
||||
test esi,esi
|
||||
jl ??shift_top
|
||||
mov [dword ptr ebx],0
|
||||
ret
|
||||
??shift_top:
|
||||
inc edi
|
||||
sub [ebx],edi
|
||||
??confi_out:
|
||||
ret
|
||||
|
||||
ENDP Confine_Rect
|
||||
|
||||
END
|
||||
114
WIN32LIB/SRCDEBUG/CRC.ASM
Normal file
114
WIN32LIB/SRCDEBUG/CRC.ASM
Normal file
@@ -0,0 +1,114 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood Library *
|
||||
;* *
|
||||
;* File Name : CRC.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : June 12, 1992 *
|
||||
;* *
|
||||
;* Last Update : February 10, 1995 [BWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Calculate_CRC :NEAR
|
||||
|
||||
CODESEG
|
||||
|
||||
; LONG Calculate_CRC(VOID *buffer, LONG length);
|
||||
PROC Calculate_CRC C near
|
||||
USES esi
|
||||
|
||||
ARG buffer:DWORD
|
||||
ARG length:DWORD
|
||||
|
||||
LOCAL crc:DWORD
|
||||
|
||||
; Load pointer to data block.
|
||||
mov [crc],0
|
||||
pushad
|
||||
mov esi,[buffer]
|
||||
cld
|
||||
|
||||
; Clear CRC to default (NULL) value.
|
||||
xor ebx,ebx
|
||||
|
||||
; Fetch the length of the data block to CRC.
|
||||
mov ecx,[length]
|
||||
jecxz short ??fini
|
||||
|
||||
; Prepare the length counters.
|
||||
mov edx,ecx
|
||||
and dl,011b
|
||||
shr ecx,2
|
||||
|
||||
; Perform the bulk of the CRC scanning.
|
||||
jecxz short ??remainder
|
||||
??accumloop:
|
||||
lodsd
|
||||
rol ebx,1
|
||||
add ebx,eax
|
||||
loop ??accumloop
|
||||
|
||||
; Handle the remainder bytes.
|
||||
??remainder:
|
||||
or dl,dl
|
||||
jz short ??fini
|
||||
mov ecx,edx
|
||||
xor eax,eax
|
||||
|
||||
and ecx,0FFFFh
|
||||
push ecx
|
||||
??nextbyte:
|
||||
lodsb
|
||||
ror eax,8
|
||||
loop ??nextbyte
|
||||
pop ecx
|
||||
neg ecx
|
||||
add ecx,4
|
||||
shl ecx,3
|
||||
ror eax,cl
|
||||
|
||||
;??nextbyte:
|
||||
; shl eax,8
|
||||
; lodsb
|
||||
; loop ??nextbyte
|
||||
rol ebx,1
|
||||
add ebx,eax
|
||||
|
||||
??fini:
|
||||
mov [crc],ebx
|
||||
popad
|
||||
mov eax,[crc]
|
||||
ret
|
||||
|
||||
ENDP Calculate_CRC
|
||||
|
||||
END
|
||||
1000
WIN32LIB/SRCDEBUG/DDRAW.CPP
Normal file
1000
WIN32LIB/SRCDEBUG/DDRAW.CPP
Normal file
File diff suppressed because it is too large
Load Diff
62
WIN32LIB/SRCDEBUG/DELAY.CPP
Normal file
62
WIN32LIB/SRCDEBUG/DELAY.CPP
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : LIBRARY *
|
||||
* *
|
||||
* File Name : DELAY.C *
|
||||
* *
|
||||
* Programmer : Christopher Yates *
|
||||
* *
|
||||
* Last Update : 27 March, 1991 [CY] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "wwstd.h"
|
||||
#include <timer.h>
|
||||
|
||||
void Delay(int duration)
|
||||
{
|
||||
unsigned long count;
|
||||
TimerClass timer(BT_SYSTEM,TRUE);
|
||||
|
||||
while (duration--) {
|
||||
count = timer.Time() + 1L;
|
||||
while (count >= timer.Time()) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#if(FALSE)
|
||||
while (duration--)
|
||||
Wait_Vert_Blank(VertBlank);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if(FALSE)
|
||||
void Vsync()
|
||||
{
|
||||
Wait_Vert_Blank(VertBlank);
|
||||
}
|
||||
#endif
|
||||
|
||||
113
WIN32LIB/SRCDEBUG/DESCMGMT.CPP
Normal file
113
WIN32LIB/SRCDEBUG/DESCMGMT.CPP
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Descriptor management *
|
||||
* *
|
||||
* File Name : DESCMGMT.CPP *
|
||||
* *
|
||||
* Programmer : Jeff Wilson *
|
||||
* *
|
||||
* Start Date : March 28, 1994 *
|
||||
* *
|
||||
* Last Update : March 28, 1994 [] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* MAP_SEGMENT_TO_ADDRESS -- Maps a physical address into a selector *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "descmgmt.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* MAP_SEGMENT_TO_ADDRESS -- Maps a physical address into a selector *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: selector UWORD The selector mapped to address. exit on error. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/25/1994 jaw: Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
ULONG Map_Segment_To_Address(ULONG address, ULONG length)
|
||||
{
|
||||
|
||||
// this function is not longer needed by RATIONAL SYSTEM DOS4GW
|
||||
// linear addressing mode.
|
||||
// a> the first megabyte of memory is mapped to linear adress 0 - 0x10000h
|
||||
// b> all other addresses are linear offset from either ds: or es:
|
||||
|
||||
/*
|
||||
UWORD segment;
|
||||
UWORD curDS;
|
||||
CD_DES desc;
|
||||
CD_DES cur_desc;
|
||||
|
||||
// allocate a selector
|
||||
if(_dos_allocmem(0, &segment) != 0) {
|
||||
Exit(1, "Allocation of Descriptor.\n");
|
||||
}
|
||||
|
||||
// get the data for this selector
|
||||
if(_dx_ldt_rd(segment, (UCHAR *)&desc) != 0) {
|
||||
Exit(1, "Reading Descriptor.\n");
|
||||
}
|
||||
|
||||
// get the data for current data segment
|
||||
curDS = GetDs();
|
||||
if(_dx_ldt_rd(curDS, (UCHAR *)&cur_desc) != 0) {
|
||||
Exit(1, "Reading Descriptor.\n");
|
||||
}
|
||||
|
||||
// set limit
|
||||
desc.limit0_15 = (USHORT)(length & 0xffff);
|
||||
desc.limit16_19 = ((UCHAR)(length >> 16L)) | DOS_32;
|
||||
|
||||
// set base address
|
||||
desc.base0_15 = (USHORT)(address & 0xffff);
|
||||
desc.base16_23 = (UCHAR)((address >> 16) & 0xff);
|
||||
desc.base24_31 = (UCHAR)((address >> 24) & 0xff);
|
||||
|
||||
// set rights mark as icurrent data segment
|
||||
desc.arights = cur_desc.arights;
|
||||
|
||||
// write to LDT selector
|
||||
if(_dx_ldt_wr(segment, (UCHAR *)&desc) != 0) {
|
||||
Exit(1, "Failed writing descriptor.\n");
|
||||
}
|
||||
|
||||
// return selector number
|
||||
return segment;
|
||||
*/
|
||||
|
||||
if ( address & 0xfff0ffff )
|
||||
Exit ( 1 , "Error mapping real address to lineal address.\n" ) ;
|
||||
|
||||
return address ;
|
||||
}
|
||||
|
||||
115
WIN32LIB/SRCDEBUG/DETPROC.ASM
Normal file
115
WIN32LIB/SRCDEBUG/DETPROC.ASM
Normal file
@@ -0,0 +1,115 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/system/rcs/detproc.asm 1.1 1994/04/18 09:13:53 jeff_wilson Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood Library *
|
||||
;* *
|
||||
;* File Name : PROC.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : May 11, 1993 *
|
||||
;* *
|
||||
;* Last Update : May 11, 1993 [JLB] *
|
||||
;* *
|
||||
;* Converted to 32Bit -- JAW *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Processor :NEAR
|
||||
|
||||
|
||||
PROC_80386 equ 0
|
||||
PROC_80486 equ 1
|
||||
PROC_80586 equ 2
|
||||
|
||||
DATASEG
|
||||
cpu_id_586 dw 0
|
||||
|
||||
CODESEG
|
||||
|
||||
PROC Processor C near
|
||||
USES ebx
|
||||
LOCAL ptype:WORD
|
||||
|
||||
pushfd
|
||||
|
||||
; At least a 386 -- check for 486.
|
||||
mov [WORD PTR ptype],PROC_80386 ; 80386
|
||||
pushfd
|
||||
pop eax
|
||||
mov ebx,eax
|
||||
xor eax,40000h
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
xor eax,ebx
|
||||
je short ??fini
|
||||
|
||||
; At least a 486 -- check for 586(Pentium)
|
||||
mov [ptype],PROC_80486 ; 80486
|
||||
|
||||
; Some machines have a problem with this fLAG
|
||||
; and thus make us think they are a 586 but they are
|
||||
; really a 486. A possible way around this is to
|
||||
; capture the Illegal instruction vector, then do
|
||||
; an instruction only available on the 586.
|
||||
|
||||
; for now this is just commented out
|
||||
pushfd
|
||||
pop eax
|
||||
mov ebx,eax
|
||||
xor eax,200000h
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
xor eax,ebx
|
||||
je short ??fini
|
||||
|
||||
; At least a 586(Pentium) -- check for higher.
|
||||
mov [ptype],PROC_80586 ; 80486
|
||||
; mov eax,1
|
||||
; DW 0fA2h ; CPUID opcode.
|
||||
; shr ax,8
|
||||
; and ax,0fh
|
||||
; inc ax
|
||||
; inc ax
|
||||
; mov [cpu_id_586],ax
|
||||
|
||||
; Final cleanup and exit.
|
||||
??fini:
|
||||
popfd
|
||||
sub eax,eax
|
||||
mov ax,[ptype]
|
||||
ret
|
||||
|
||||
ENDP Processor
|
||||
|
||||
END
|
||||
165
WIN32LIB/SRCDEBUG/DEVICES.ASM
Normal file
165
WIN32LIB/SRCDEBUG/DEVICES.ASM
Normal file
@@ -0,0 +1,165 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/system/rcs/devices.asm 1.2 1994/04/28 12:41:41 jeff_wilson Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : LIBRARY *
|
||||
;* *
|
||||
;* File Name : DEVICES.ASM *
|
||||
;* *
|
||||
;* Programmer : Christopher Yates *
|
||||
;* *
|
||||
;* Last Update : 12 December, 1990 [CY] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* *
|
||||
; VOID Get_Devices(VOID); *
|
||||
; WORD Is_Device_Real(WORD drive); *
|
||||
;* *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL Get_Devices :NEAR
|
||||
GLOBAL Is_Device_Real :NEAR
|
||||
|
||||
GLOBAL MaxDevice :BYTE
|
||||
GLOBAL DefaultDrive :BYTE
|
||||
|
||||
; ----------------------------------------------------------------
|
||||
;
|
||||
; Here are prototypes for the routines defined within this module:
|
||||
;
|
||||
; VOID Get_Devices(VOID);
|
||||
; WORD Is_Device_Real(WORD drive);
|
||||
;
|
||||
; ----------------------------------------------------------------
|
||||
|
||||
CODESEG
|
||||
|
||||
;***********************************************************
|
||||
;
|
||||
; GET_DEVICES
|
||||
;
|
||||
; VOID Get_Devices(VOID);
|
||||
;
|
||||
; This routine establishes the default disk drive and the maximum drive
|
||||
; available in the current system.
|
||||
;
|
||||
;*
|
||||
DOS equ 21h
|
||||
|
||||
PROC Get_Devices C near
|
||||
USES eax,ebx,edx
|
||||
|
||||
sub eax,eax
|
||||
mov ah,25 ; get current drive service
|
||||
int DOS ; drive returned in al
|
||||
mov [DefaultDrive],al ; save it
|
||||
mov dl,al
|
||||
mov ah,14 ; set current as current drive
|
||||
int DOS
|
||||
dec al ; al = max drives, make it n - 1
|
||||
xor ah,ah ; clear high byte
|
||||
mov edx,eax ; use dx to go backward to find out
|
||||
sub ebx,ebx
|
||||
|
||||
??back_loop:
|
||||
mov bl,dl ; find out about the drive in dl
|
||||
inc bl
|
||||
mov eax,0440Eh ; get the physical drive associated
|
||||
int DOS ; with this letter
|
||||
jnc short ??later ; if c clear, no error
|
||||
cmp al,0Fh ; was it invalid? (0Fh = invalid)
|
||||
jne short ??later ; yes, so LATER
|
||||
dec edx
|
||||
jmp ??back_loop ; try, try again
|
||||
|
||||
??later:
|
||||
mov eax,edx ; restore ax
|
||||
mov [MaxDevice],al ; save the max drive #
|
||||
|
||||
ret
|
||||
|
||||
ENDP Get_Devices
|
||||
|
||||
;***************************************************************
|
||||
|
||||
|
||||
;***************************************************************
|
||||
;
|
||||
; IS_DEVICE_REAL
|
||||
;
|
||||
; WORD Is_Device_Real(WORD drive);
|
||||
;
|
||||
; This routine will tell whether or not a device is a true
|
||||
; phisical one. Send it the drive # to check.
|
||||
;
|
||||
;*
|
||||
PROC Is_Device_Real C near
|
||||
USES ebx,edx
|
||||
ARG drive:WORD
|
||||
|
||||
sub edx,edx
|
||||
mov dx,[drive]
|
||||
|
||||
??next_drive:
|
||||
push ebx
|
||||
mov bl,dl ; find out about the drive in dl
|
||||
inc bl
|
||||
mov eax,0440Eh ; get the physical drive associated
|
||||
int DOS ; with this letter
|
||||
pop ebx
|
||||
|
||||
jnc short ??it_is_real ; jump if no error
|
||||
cmp al,01 ; 1 = invalid command,
|
||||
; 0F = invalid device
|
||||
je short ??real ; 1? it is ok (RAM device)
|
||||
jmp short ??invalid ; 0Fh, it was not a device
|
||||
|
||||
??it_is_real:
|
||||
cmp al,0 ; was it a fixed device?
|
||||
je short ??real ; yes, it's ok
|
||||
dec al ; make it a drive #
|
||||
cmp al,dl ; is it a valid drive?
|
||||
je short ??real
|
||||
|
||||
??invalid: ; The device is invalid.
|
||||
mov eax,0
|
||||
jmp short ??out
|
||||
|
||||
??real: ; Return true, for valid device.
|
||||
mov eax,1
|
||||
|
||||
??out:
|
||||
ret
|
||||
ENDP Is_Device_Real
|
||||
|
||||
;***************************************************************
|
||||
|
||||
END
|
||||
|
||||
204
WIN32LIB/SRCDEBUG/DEVTABLE.ASM
Normal file
204
WIN32LIB/SRCDEBUG/DEVTABLE.ASM
Normal file
@@ -0,0 +1,204 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/system/rcs/devtable.asm 1.2 1994/04/28 12:41:29 jeff_wilson Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : LIBRARY *
|
||||
;* *
|
||||
;* File Name : DEVTABLE.ASM *
|
||||
;* *
|
||||
;* Programmer : Christopher Yates *
|
||||
;* *
|
||||
;* Last Update : 12 December, 1990 [CY] *
|
||||
;* *
|
||||
;* Updated to 32bit protected mode JAW *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* *
|
||||
; VOID Init_Device_Table(BYTE *table); *
|
||||
; WORD Max_Device(VOID); *
|
||||
;* *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
LOCALS ??
|
||||
|
||||
DOS equ 21h
|
||||
|
||||
GLOBAL Max_Device :NEAR
|
||||
GLOBAL get_max_device :NEAR
|
||||
GLOBAL Init_Device_Table :NEAR
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
; ----------------------------------------------------------------
|
||||
;
|
||||
; Here are prototypes for the routines defined within this module:
|
||||
;
|
||||
; VOID Init_Device_Table(BYTE *table);
|
||||
; WORD Max_Device(VOID);
|
||||
;
|
||||
; ----------------------------------------------------------------
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; WORD Max_Device(VOID);
|
||||
;
|
||||
|
||||
PROC Max_Device C NEAR
|
||||
|
||||
call get_max_device ; get max devices in ax
|
||||
ret
|
||||
|
||||
ENDP Max_Device
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
;
|
||||
; returns max devices in AX
|
||||
|
||||
PROC get_max_device C NEAR
|
||||
USES ebx,edx
|
||||
|
||||
mov ah,25 ; get current drive service
|
||||
int DOS ; drive returned in al
|
||||
mov dl,al
|
||||
mov ah,14 ; set current as current drive
|
||||
int DOS
|
||||
dec al ; al = max drives, make it n - 1
|
||||
xor ah,ah ; clear high byte
|
||||
sub edx,edx
|
||||
mov edx,eax ; use dx to go backward to find out
|
||||
; if DOS is lying (down)
|
||||
|
||||
??back_loop:
|
||||
push ds
|
||||
push ebx
|
||||
mov bl,dl ; find out about the drive in dl
|
||||
inc bl
|
||||
mov eax,0440Eh ; get the physical drive associated
|
||||
int DOS ; with this letter
|
||||
pop ebx
|
||||
pop ds
|
||||
jnc short ??later ; if c clear, no error
|
||||
|
||||
cmp al,0Fh ; was it invalid? (0Fh = invalid)
|
||||
jne short ??later ; yes, so LATER
|
||||
|
||||
dec edx
|
||||
jmp ??back_loop ; try, try again
|
||||
|
||||
??later:
|
||||
mov eax,edx ; restore ax
|
||||
ret
|
||||
|
||||
ENDP get_max_device
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; VOID Init_Device_Table(BYTE *table);
|
||||
;
|
||||
|
||||
PROC Init_Device_Table C NEAR
|
||||
|
||||
USES eax,ebx,edi,edx
|
||||
ARG table:DWORD ; Pointer to device table.
|
||||
LOCAL curr_drive:BYTE ; Copy of current drive number.
|
||||
|
||||
mov edi,[table]
|
||||
|
||||
call get_max_device ; get max devices in ax
|
||||
add edi,eax
|
||||
std
|
||||
mov [curr_drive],al ; save it
|
||||
|
||||
??next_drive:
|
||||
mov dl,[curr_drive] ; copy current drive #
|
||||
cmp dl,0FFh ; are we done?
|
||||
je short ??later ; if so, later
|
||||
|
||||
dec [curr_drive] ; dec our local drive #
|
||||
|
||||
push ds
|
||||
push ebx
|
||||
mov bl,dl ; find out about the drive in dl
|
||||
inc bl
|
||||
mov eax,0440Eh ; get the physical drive associated
|
||||
int DOS ; with this letter
|
||||
pop ebx
|
||||
pop ds
|
||||
|
||||
jnc short ??it_is_real ; jump if no error
|
||||
cmp al,01 ; 1 = invalid command,
|
||||
; 0F = invalid device
|
||||
je short ??set_as_current ; 1? it is ok (RAM device)
|
||||
jmp short ??invalid ; 0Fh, it was not a device
|
||||
|
||||
|
||||
??it_is_real:
|
||||
cmp al,0 ; was it a fixed device?
|
||||
je short ??set_as_current ; yes, it's ok
|
||||
|
||||
dec al ; make it a drive #
|
||||
cmp al,dl ; is it a valid drive?
|
||||
je short ??set_as_current
|
||||
|
||||
;
|
||||
; Device was logical and not active, so clear the entry
|
||||
;
|
||||
??invalid:
|
||||
xor al,al
|
||||
stosb
|
||||
cmp [curr_drive],0 ; are we done checking?
|
||||
jge ??next_drive ; no, go to next
|
||||
|
||||
jmp short ??later
|
||||
|
||||
??set_as_current:
|
||||
mov al,1
|
||||
stosb
|
||||
cmp dl,0 ; are we before the A drive (invalid)
|
||||
jl short ??later ; yes, we are done checking
|
||||
|
||||
jmp ??next_drive ; keep processing
|
||||
|
||||
??later:
|
||||
cld
|
||||
ret
|
||||
|
||||
ENDP Init_Device_Table
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
END
|
||||
|
||||
328
WIN32LIB/SRCDEBUG/DIPTHONG.CPP
Normal file
328
WIN32LIB/SRCDEBUG/DIPTHONG.CPP
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: g:/library/source/rcs/./dipthong.c 1.15 1994/05/20 15:35:17 joe_bostic Exp $ */
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : DIPTHONG.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : February 23, 1992 *
|
||||
* *
|
||||
* Last Update : February 13, 1995 [BWG] *
|
||||
* *
|
||||
* DIGRAM or DIATOMIC encoding is the correct term for this method. *
|
||||
* This is a fixed dictionary digram encoding optimized for English text. *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Extract_String -- Extracts a string pointer from a string data block. *
|
||||
* UnDip_Text -- Undipthongs a text string into specified buffer. *
|
||||
* Dip_Text -- Compresses text by using dipthonging. *
|
||||
* Fixup_Text -- Converts dipthonged foreign text into normal text. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//#include "function.h"
|
||||
//#include "ems.h"
|
||||
#include <keyboard.h>
|
||||
#include "dipthong.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Fixup_Text -- Converts dipthonged foreign text into normal text. *
|
||||
* *
|
||||
* Takes text that has been processed (or undipped) to hold foriegn *
|
||||
* language character pairs (needed for Window_Print) and converts it *
|
||||
* so that Text_Print will print it properly. Typically this would be *
|
||||
* used after text has been undipped but before it will be Text_Printed.*
|
||||
* Text that is to be Window_Printed doesn't and mustn't have its text *
|
||||
* processed by this routine. *
|
||||
* *
|
||||
* INPUT: source -- Pointer to the source string to process. *
|
||||
* *
|
||||
* dest -- Destination buffer to hold the processed string. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: This routine will only reduce the size of the string if it *
|
||||
* modifies it at all. Because of this it is quite legal to *
|
||||
* pass the same pointers to this routine so that it will *
|
||||
* modify the string "in place". *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/13/1993 JLB : Created. *
|
||||
* 10/06/1994 JLB : Handles source string in EMS. *
|
||||
*=========================================================================*/
|
||||
void Fixup_Text(char const *source, char *dest)
|
||||
{
|
||||
if (source && dest) {
|
||||
char const *src;
|
||||
char temp;
|
||||
|
||||
src = source;
|
||||
while (*src) {
|
||||
if (*src == KA_EXTEND) {
|
||||
src++;
|
||||
temp = *src++;
|
||||
temp += 127;
|
||||
*dest++ = temp;
|
||||
} else {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
*dest = '\0';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Dip_Text -- Compresses text by using dipthonging. *
|
||||
* *
|
||||
* This routine is used to compress text by using dipthonging. Text *
|
||||
* that is compressed in this fashion usually is reduced in size by *
|
||||
* approximately 40%. *
|
||||
* *
|
||||
* INPUT: source -- Pointer to the source string to compress. *
|
||||
* *
|
||||
* dest -- Pointer to the buffer that will hold the dipthong *
|
||||
* text output. *
|
||||
* *
|
||||
* OUTPUT: Returns the number of bytes output into the output buffer. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/13/1993 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
int Dip_Text(char const *source, char *dest)
|
||||
{
|
||||
unsigned char first, // First character in pair.
|
||||
next; // Second character in pair.
|
||||
int common, // Common character index.
|
||||
dipthong; // Dipthong character index.
|
||||
|
||||
unsigned long length=0; // Length of output string
|
||||
|
||||
first = *source++;
|
||||
next = *source;
|
||||
while (first) {
|
||||
|
||||
if (first > 127) {
|
||||
|
||||
/*
|
||||
** Characters greater than 127 cannot be dipthonged. They must
|
||||
** be preceeded with an extended character code.
|
||||
*/
|
||||
*dest++ = (char)KA_EXTEND;
|
||||
first -= 127;
|
||||
length++;
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Normal characters can be dipthonged. First see if there is a
|
||||
** match in the Common table.
|
||||
*/
|
||||
for (common = 0; common < 16; common++) {
|
||||
if (Common[common] == first) {
|
||||
|
||||
/*
|
||||
** Common character found. See if there is a matching
|
||||
** Dipthong character.
|
||||
*/
|
||||
for (dipthong = 0; dipthong < 8; dipthong++) {
|
||||
if (Dipthong[common][dipthong] == next) {
|
||||
first = (unsigned char) (common << 3);
|
||||
first |= (unsigned char)dipthong;
|
||||
first |= (unsigned char)0x80;
|
||||
source++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Output the translated character to the destination buffer.
|
||||
*/
|
||||
*dest++ = first;
|
||||
length++;
|
||||
|
||||
first = *source++;
|
||||
next = *source;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
|
||||
return(length);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* UnDip_Text -- Undipthongs a text string into specified buffer. *
|
||||
* *
|
||||
* This routine is used to undipthong a text string and place the *
|
||||
* undipped text into the buffer specified. Since dipthonged text is *
|
||||
* compressed, in order for the text to be used it must be undipped *
|
||||
* first. *
|
||||
* *
|
||||
* INPUT: source -- Pointer to the dipped string. *
|
||||
* *
|
||||
* dest -- Pointer to the destination buffer. *
|
||||
* *
|
||||
* OUTPUT: Returns the number of bytes placed into the destination *
|
||||
* buffer. *
|
||||
* *
|
||||
* WARNINGS: Be sure the destination buffer is big enough to hold the *
|
||||
* undipped text. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/13/1993 JLB : Created. *
|
||||
* 10/06/1994 JLB : Handles source string in EMS. *
|
||||
*=========================================================================*/
|
||||
int UnDip_Text(char const *source, char *dest)
|
||||
{
|
||||
int c; // Source input character.
|
||||
int common; // Common character index.
|
||||
int len; // Length of output string.
|
||||
char const *src;
|
||||
|
||||
len = 0; // Presume no translation.
|
||||
|
||||
/*
|
||||
** Sweep through the source text and dipthong it.
|
||||
*/
|
||||
src = source;
|
||||
c = *src++;
|
||||
while (c) {
|
||||
|
||||
/*
|
||||
** Convert a dipthong character into it's component
|
||||
** ASCII characters.
|
||||
*/
|
||||
if (c & 0x80) {
|
||||
c &= 0x7F;
|
||||
|
||||
common = (c & 0x78) >> 3;
|
||||
|
||||
*dest++ = Common[common];
|
||||
len++;
|
||||
|
||||
c = Dipthong[common][c & 0x07];
|
||||
}
|
||||
|
||||
*dest++ = (unsigned char)c;
|
||||
len++;
|
||||
|
||||
c = *src++;
|
||||
}
|
||||
|
||||
/*
|
||||
** End the output text with a '\0'.
|
||||
*/
|
||||
*dest++ = '\0';
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Extract_String -- Extracts a string pointer from a string data block. *
|
||||
* *
|
||||
* This routine is used to find a pointer to the specified string *
|
||||
* inside a string block. String data blocks are created with the *
|
||||
* TEXTMAKE utility. The data block my reside in XMS or EMS memory, *
|
||||
* but of course the returned string pointer will also point to *
|
||||
* such memory. In this case, the string must be placed in real *
|
||||
* memory before it can be used. *
|
||||
* *
|
||||
* INPUT: data -- Pointer to the string data block. *
|
||||
* *
|
||||
* string -- The string number to extract (if < 0 then NULL *
|
||||
* is returned). *
|
||||
* *
|
||||
* OUTPUT: Returns with pointer to the string number specified. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/13/1993 JLB : Created. *
|
||||
* 08/13/1993 JLB : Handles EMS or XMS data pointer. *
|
||||
*=========================================================================*/
|
||||
|
||||
#define TXT_GUEST 4567+3
|
||||
#define TXT_LOGIN 4567+4
|
||||
#define TXT_LOGIN_TO_INTERNET 4567+5
|
||||
#define TXT_YOUR_HANDLE 4567+6
|
||||
#define TXT_YOUR_PASSWORD 4567+7
|
||||
#define TXT_INTERNET_HOST 4567+8
|
||||
#define TXT_INTERNET_JOIN 4567+9
|
||||
#define TXT_INTERNET_GAME_TYPE 4567+10
|
||||
#define TXT_JOIN_INTERNET_GAME 4567+11
|
||||
#define TXT_ENTER_IP_ADDRESS 4567+12
|
||||
#define TXT_WINSOCK_CONNECTING 4567+13
|
||||
#define TXT_WINSOCK_NOT_CONNECTING 4567+14
|
||||
#define TXT_WINSOCK_UNABLE_TO_CONNECT_TO_SERVER 4567+15
|
||||
#define TXT_WINSOCK_CONTACTING_SERVER 4567+16
|
||||
#define TXT_WINSOCK_SERVER_ADDRESS_LOOKUP_FAILED 4567+17
|
||||
#define TXT_WINSOCK_UNABLE_TO_ACCEPT_CLIENT 4567+18
|
||||
#define TXT_WINSOCK_UNABLE_TO_CONNECT 4567+19
|
||||
#define TXT_WINSOCK_CONNECTION_LOST 4567+20
|
||||
#define TXT_WINSOCK_RESOLVING_HOST_ADDRESS 4567+21
|
||||
|
||||
static char InternetTxt[22][40]={
|
||||
"Internet H2H",
|
||||
"Host Internet Game",
|
||||
"Join Internet Game",
|
||||
"Guest",
|
||||
"Login",
|
||||
"Login to Planet Westwood",
|
||||
"Planet Westwood Handle",
|
||||
"Planet Westwood Password",
|
||||
"Host Game",
|
||||
"Join Game",
|
||||
"Choose Type of Internet Game",
|
||||
"Join Internet Game",
|
||||
"Address of Host",
|
||||
"Connecting...",
|
||||
"Connection Error!",
|
||||
"Unable to connect to host!",
|
||||
"Connecting to host...",
|
||||
"Unable to resolve host address!",
|
||||
"Unable to accept client connection",
|
||||
"Unable to connect!",
|
||||
"Connection lost!",
|
||||
"Resolving address of host..."
|
||||
};
|
||||
|
||||
char *Extract_String(void const *data, int string)
|
||||
{
|
||||
unsigned short int const *ptr;
|
||||
|
||||
if (!data || string < 0) return(NULL);
|
||||
|
||||
if (string >= 4567) return (InternetTxt[string-4567]);
|
||||
|
||||
ptr = (unsigned short int const *)data;
|
||||
return (((char*)data) + ptr[string]);
|
||||
}
|
||||
464
WIN32LIB/SRCDEBUG/DRAWLINE.ASM
Normal file
464
WIN32LIB/SRCDEBUG/DRAWLINE.ASM
Normal file
@@ -0,0 +1,464 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Library *
|
||||
;* *
|
||||
;* File Name : DRAWLINE.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil W. Gorrow *
|
||||
;* *
|
||||
;* Start Date : June 16, 1994 *
|
||||
;* *
|
||||
;* Last Update : August 30, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* VVC::Scale -- Scales a virtual viewport to another virtual viewport *
|
||||
;* Normal_Draw -- jump loc for drawing scaled line of normal pixel *
|
||||
;* __DRAW_LINE -- Assembly routine to draw a line *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport *
|
||||
;* *
|
||||
;* INPUT: WORD sx_pixel - the starting x pixel position *
|
||||
;* WORD sy_pixel - the starting y pixel position *
|
||||
;* WORD dx_pixel - the destination x pixel position *
|
||||
;* WORD dy_pixel - the destination y pixel position *
|
||||
;* WORD color - the color of the line to draw *
|
||||
;* *
|
||||
;* Bounds Checking: Compares sx_pixel, sy_pixel, dx_pixel and dy_pixel *
|
||||
;* with the graphic viewport it has been assigned to. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/16/1994 PWG : Created. *
|
||||
;* 08/30/1994 IML : Fixed clipping bug. *
|
||||
;*=========================================================================*
|
||||
PROC Buffer_Draw_Line C NEAR
|
||||
USES eax,ebx,ecx,edx,esi,edi
|
||||
|
||||
;*==================================================================
|
||||
;* Define the arguements that the function takes.
|
||||
;*==================================================================
|
||||
ARG this_object:DWORD ; associated graphic view port
|
||||
ARG x1_pixel:DWORD ; the start x pixel position
|
||||
ARG y1_pixel:DWORD ; the start y pixel position
|
||||
ARG x2_pixel:DWORD ; the dest x pixel position
|
||||
ARG y2_pixel:DWORD ; the dest y pixel position
|
||||
ARG color:DWORD ; the color we are drawing
|
||||
|
||||
;*==================================================================
|
||||
;* Define the local variables that we will use on the stack
|
||||
;*==================================================================
|
||||
LOCAL clip_min_x:DWORD
|
||||
LOCAL clip_max_x:DWORD
|
||||
LOCAL clip_min_y:DWORD
|
||||
LOCAL clip_max_y:DWORD
|
||||
LOCAL clip_var:DWORD
|
||||
LOCAL accum:DWORD
|
||||
LOCAL bpr:DWORD
|
||||
|
||||
;*==================================================================
|
||||
;* Take care of find the clip minimum and maximums
|
||||
;*==================================================================
|
||||
mov ebx,[this_object]
|
||||
xor eax,eax
|
||||
mov [clip_min_x],eax
|
||||
mov [clip_min_y],eax
|
||||
mov eax,[(GraphicViewPort ebx).GVPWidth]
|
||||
mov [clip_max_x],eax
|
||||
add eax,[(GraphicViewPort ebx).GVPXAdd]
|
||||
add eax,[(GraphicViewPort ebx).GVPPitch]
|
||||
mov [bpr],eax
|
||||
mov eax,[(GraphicViewPort ebx).GVPHeight]
|
||||
mov [clip_max_y],eax
|
||||
|
||||
;*==================================================================
|
||||
;* Adjust max pixels as they are tested inclusively.
|
||||
;*==================================================================
|
||||
dec [clip_max_x]
|
||||
dec [clip_max_y]
|
||||
|
||||
;*==================================================================
|
||||
;* Set the registers with the data for drawing the line
|
||||
;*==================================================================
|
||||
mov eax,[x1_pixel] ; eax = start x pixel position
|
||||
mov ebx,[y1_pixel] ; ebx = start y pixel position
|
||||
mov ecx,[x2_pixel] ; ecx = dest x pixel position
|
||||
mov edx,[y2_pixel] ; edx = dest y pixel position
|
||||
|
||||
;*==================================================================
|
||||
;* This is the section that "pushes" the line into bounds.
|
||||
;* I have marked the section with PORTABLE start and end to signify
|
||||
;* how much of this routine is 100% portable between graphics modes.
|
||||
;* It was just as easy to have variables as it would be for constants
|
||||
;* so the global vars ClipMaxX,ClipMinY,ClipMaxX,ClipMinY are used
|
||||
;* to clip the line (default is the screen)
|
||||
;* PORTABLE start
|
||||
;*==================================================================
|
||||
|
||||
cmp eax,[clip_min_x]
|
||||
jl short ??clip_it
|
||||
cmp eax,[clip_max_x]
|
||||
jg short ??clip_it
|
||||
cmp ebx,[clip_min_y]
|
||||
jl short ??clip_it
|
||||
cmp ebx,[clip_max_y]
|
||||
jg short ??clip_it
|
||||
cmp ecx,[clip_min_x]
|
||||
jl short ??clip_it
|
||||
cmp ecx,[clip_max_x]
|
||||
jg short ??clip_it
|
||||
cmp edx,[clip_min_y]
|
||||
jl short ??clip_it
|
||||
cmp edx,[clip_max_y]
|
||||
jle short ??on_screen
|
||||
|
||||
;*==================================================================
|
||||
;* Takes care off clipping the line.
|
||||
;*==================================================================
|
||||
??clip_it:
|
||||
call NEAR PTR ??set_bits
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
mov edi,esi
|
||||
call NEAR PTR ??set_bits
|
||||
mov [clip_var],edi
|
||||
or [clip_var],esi
|
||||
jz short ??on_screen
|
||||
test edi,esi
|
||||
jne short ??off_screen
|
||||
shl esi,2
|
||||
call [DWORD PTR cs:??clip_tbl+esi]
|
||||
jc ??clip_it
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
shl edi,2
|
||||
call [DWORD PTR cs:??clip_tbl+edi]
|
||||
jmp ??clip_it
|
||||
|
||||
??on_screen:
|
||||
jmp ??draw_it
|
||||
|
||||
??off_screen:
|
||||
jmp ??out
|
||||
|
||||
;*==================================================================
|
||||
;* Jump table for clipping conditions
|
||||
;*==================================================================
|
||||
??clip_tbl DD ??nada,??a_up,??a_dwn,??nada
|
||||
DD ??a_lft,??a_lft,??a_dwn,??nada
|
||||
DD ??a_rgt,??a_up,??a_rgt,??nada
|
||||
DD ??nada,??nada,??nada,??nada
|
||||
|
||||
??nada:
|
||||
clc
|
||||
retn
|
||||
|
||||
??a_up:
|
||||
mov esi,[clip_min_y]
|
||||
call NEAR PTR ??clip_vert
|
||||
stc
|
||||
retn
|
||||
|
||||
??a_dwn:
|
||||
mov esi,[clip_max_y]
|
||||
neg esi
|
||||
neg ebx
|
||||
neg edx
|
||||
call NEAR PTR ??clip_vert
|
||||
neg ebx
|
||||
neg edx
|
||||
stc
|
||||
retn
|
||||
|
||||
;*==================================================================
|
||||
;* xa'=xa+[(miny-ya)(xb-xa)/(yb-ya)]
|
||||
;*==================================================================
|
||||
??clip_vert:
|
||||
push edx
|
||||
push eax
|
||||
mov [clip_var],edx ; clip_var = yb
|
||||
sub [clip_var],ebx ; clip_var = (yb-ya)
|
||||
neg eax ; eax=-xa
|
||||
add eax,ecx ; (ebx-xa)
|
||||
mov edx,esi ; edx=miny
|
||||
sub edx,ebx ; edx=(miny-ya)
|
||||
imul edx
|
||||
idiv [clip_var]
|
||||
pop edx
|
||||
add eax,edx
|
||||
pop edx
|
||||
mov ebx,esi
|
||||
retn
|
||||
|
||||
??a_lft:
|
||||
mov esi,[clip_min_x]
|
||||
call NEAR PTR ??clip_horiz
|
||||
stc
|
||||
retn
|
||||
|
||||
??a_rgt:
|
||||
mov esi,[clip_max_x]
|
||||
neg eax
|
||||
neg ecx
|
||||
neg esi
|
||||
call NEAR PTR ??clip_horiz
|
||||
neg eax
|
||||
neg ecx
|
||||
stc
|
||||
retn
|
||||
|
||||
;*==================================================================
|
||||
;* ya'=ya+[(minx-xa)(yb-ya)/(xb-xa)]
|
||||
;*==================================================================
|
||||
??clip_horiz:
|
||||
push edx
|
||||
mov [clip_var],ecx ; clip_var = xb
|
||||
sub [clip_var],eax ; clip_var = (xb-xa)
|
||||
sub edx,ebx ; edx = (yb-ya)
|
||||
neg eax ; eax = -xa
|
||||
add eax,esi ; eax = (minx-xa)
|
||||
imul edx ; eax = (minx-xa)(yb-ya)
|
||||
idiv [clip_var] ; eax = (minx-xa)(yb-ya)/(xb-xa)
|
||||
add ebx,eax ; ebx = xa+[(minx-xa)(yb-ya)/(xb-xa)]
|
||||
pop edx
|
||||
mov eax,esi
|
||||
retn
|
||||
|
||||
;*==================================================================
|
||||
;* Sets the condition bits
|
||||
;*==================================================================
|
||||
??set_bits:
|
||||
xor esi,esi
|
||||
cmp ebx,[clip_min_y] ; if y >= top its not up
|
||||
jge short ??a_not_up
|
||||
or esi,1
|
||||
|
||||
??a_not_up:
|
||||
cmp ebx,[clip_max_y] ; if y <= bottom its not down
|
||||
jle short ??a_not_down
|
||||
or esi,2
|
||||
|
||||
??a_not_down:
|
||||
cmp eax,[clip_min_x] ; if x >= left its not left
|
||||
jge short ??a_not_left
|
||||
or esi,4
|
||||
|
||||
??a_not_left:
|
||||
cmp eax,[clip_max_x] ; if x <= right its not right
|
||||
jle short ??a_not_right
|
||||
or esi,8
|
||||
|
||||
??a_not_right:
|
||||
retn
|
||||
|
||||
;*==================================================================
|
||||
;* Draw the line to the screen.
|
||||
;* PORTABLE end
|
||||
;*==================================================================
|
||||
??draw_it:
|
||||
sub edx,ebx ; see if line is being draw down
|
||||
jnz short ??not_hline ; if not then its not a hline
|
||||
jmp short ??hline ; do special case h line
|
||||
|
||||
??not_hline:
|
||||
jg short ??down ; if so there is no need to rev it
|
||||
neg edx ; negate for actual pixel length
|
||||
xchg eax,ecx ; swap x's to rev line draw
|
||||
sub ebx,edx ; get old edx
|
||||
|
||||
??down:
|
||||
push edx
|
||||
push eax
|
||||
mov eax,[bpr]
|
||||
mul ebx
|
||||
mov ebx,eax
|
||||
mov eax,[this_object]
|
||||
add ebx,[(GraphicViewPort eax).GVPOffset]
|
||||
pop eax
|
||||
pop edx
|
||||
|
||||
mov esi,1 ; assume a right mover
|
||||
sub ecx,eax ; see if line is right
|
||||
jnz short ??not_vline ; see if its a vertical line
|
||||
jmp ??vline
|
||||
|
||||
??not_vline:
|
||||
jg short ??right ; if so, the difference = length
|
||||
|
||||
??left:
|
||||
neg ecx ; else negate for actual pixel length
|
||||
neg esi ; negate counter to move left
|
||||
|
||||
??right:
|
||||
cmp ecx,edx ; is it a horiz or vert line
|
||||
jge short ??horiz ; if ecx > edx then |x|>|y| or horiz
|
||||
|
||||
??vert:
|
||||
xchg ecx,edx ; make ecx greater and edx lesser
|
||||
mov edi,ecx ; set greater
|
||||
mov [accum],ecx ; set accumulator to 1/2 greater
|
||||
shr [accum],1
|
||||
|
||||
;*==================================================================
|
||||
;* at this point ...
|
||||
;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater;
|
||||
;* esi=adder; accum=accumulator
|
||||
;* in a vertical loop the adder is conditional and the inc constant
|
||||
;*==================================================================
|
||||
??vert_loop:
|
||||
add ebx,eax
|
||||
mov eax,[color]
|
||||
|
||||
??v_midloop:
|
||||
mov [ebx],al
|
||||
dec ecx
|
||||
jl ??out
|
||||
add ebx,[bpr]
|
||||
sub [accum],edx ; sub the lesser
|
||||
jge ??v_midloop ; any line could be new
|
||||
add [accum],edi ; add greater for new accum
|
||||
add ebx,esi ; next pixel over
|
||||
jmp ??v_midloop
|
||||
|
||||
??horiz:
|
||||
mov edi,ecx ; set greater
|
||||
mov [accum],ecx ; set accumulator to 1/2 greater
|
||||
shr [accum],1
|
||||
|
||||
;*==================================================================
|
||||
;* at this point ...
|
||||
;* eax=xpos ; ebx=page line offset; ecx=counter; edx=lesser; edi=greater;
|
||||
;* esi=adder; accum=accumulator
|
||||
;* in a vertical loop the adder is conditional and the inc constant
|
||||
;*==================================================================
|
||||
??horiz_loop:
|
||||
add ebx,eax
|
||||
mov eax,[color]
|
||||
|
||||
??h_midloop:
|
||||
mov [ebx],al
|
||||
dec ecx ; dec counter
|
||||
jl ??out ; end of line
|
||||
add ebx,esi
|
||||
sub [accum],edx ; sub the lesser
|
||||
jge ??h_midloop
|
||||
add [accum],edi ; add greater for new accum
|
||||
add ebx,[bpr] ; goto next line
|
||||
jmp ??h_midloop
|
||||
|
||||
;*==================================================================
|
||||
;* Special case routine for horizontal line draws
|
||||
;*==================================================================
|
||||
??hline:
|
||||
cmp eax,ecx ; make eax < ecx
|
||||
jl short ??hl_ac
|
||||
xchg eax,ecx
|
||||
|
||||
??hl_ac:
|
||||
sub ecx,eax ; get len
|
||||
inc ecx
|
||||
|
||||
push edx
|
||||
push eax
|
||||
mov eax,[bpr]
|
||||
mul ebx
|
||||
mov ebx,eax
|
||||
mov eax,[this_object]
|
||||
add ebx,[(GraphicViewPort eax).GVPOffset]
|
||||
pop eax
|
||||
pop edx
|
||||
add ebx,eax
|
||||
mov edi,ebx
|
||||
cmp ecx,15
|
||||
jg ??big_line
|
||||
mov al,[byte color]
|
||||
rep stosb ; write as many words as possible
|
||||
jmp short ??out ; get outt
|
||||
|
||||
|
||||
??big_line:
|
||||
mov al,[byte color]
|
||||
mov ah,al
|
||||
mov ebx,eax
|
||||
shl eax,16
|
||||
mov ax,bx
|
||||
test edi,3
|
||||
jz ??aligned
|
||||
mov [edi],al
|
||||
inc edi
|
||||
dec ecx
|
||||
test edi,3
|
||||
jz ??aligned
|
||||
mov [edi],al
|
||||
inc edi
|
||||
dec ecx
|
||||
test edi,3
|
||||
jz ??aligned
|
||||
mov [edi],al
|
||||
inc edi
|
||||
dec ecx
|
||||
|
||||
??aligned:
|
||||
mov ebx,ecx
|
||||
shr ecx,2
|
||||
rep stosd
|
||||
mov ecx,ebx
|
||||
and ecx,3
|
||||
rep stosb
|
||||
jmp ??out
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* a special case routine for vertical line draws
|
||||
;*==================================================================
|
||||
??vline:
|
||||
mov ecx,edx ; get length of line to draw
|
||||
inc ecx
|
||||
add ebx,eax
|
||||
mov eax,[color]
|
||||
|
||||
??vl_loop:
|
||||
mov [ebx],al ; store bit
|
||||
add ebx,[bpr]
|
||||
dec ecx
|
||||
jnz ??vl_loop
|
||||
|
||||
??out:
|
||||
ret
|
||||
ENDP Buffer_Draw_Line
|
||||
|
||||
|
||||
END
|
||||
68
WIN32LIB/SRCDEBUG/DRAWRECT.CPP
Normal file
68
WIN32LIB/SRCDEBUG/DRAWRECT.CPP
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 Bit Library *
|
||||
* *
|
||||
* File Name : DRAWRECT.C *
|
||||
* *
|
||||
* Programmer : Christopher Yates *
|
||||
* *
|
||||
* Last Update : August 20, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Draw_Rect -- Draws a rectangle to the LogicPage. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "gbuffer.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Draw_Rect -- Draws a rectangle to the LogicPage. *
|
||||
* *
|
||||
* This routine will draw a rectangle to the LogicPage. The rectangle *
|
||||
* doesn't have to be aligned on the vertical or horizontal axis. In *
|
||||
* fact, it doesn't even have to be a rectangle. The "square" can be *
|
||||
* skewed. *
|
||||
* *
|
||||
* INPUT: x1_pixel, y1_pixel -- One corner. *
|
||||
* *
|
||||
* x2_pixel, y2_pixel -- The other corner. *
|
||||
* *
|
||||
* color -- The color to draw the lines. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: None, but the rectangle will be clipped to the current *
|
||||
* draw line clipping rectangle. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/20/1993 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
VOID GraphicViewPortClass::Draw_Rect(int x1_pixel, int y1_pixel, int x2_pixel, int y2_pixel, unsigned char color)
|
||||
{
|
||||
Lock();
|
||||
Draw_Line(x1_pixel, y1_pixel, x2_pixel, y1_pixel, color);
|
||||
Draw_Line(x1_pixel, y2_pixel, x2_pixel, y2_pixel, color);
|
||||
Draw_Line(x1_pixel, y1_pixel, x1_pixel, y2_pixel, color);
|
||||
Draw_Line(x2_pixel, y1_pixel, x2_pixel, y2_pixel, color);
|
||||
Unlock();
|
||||
}
|
||||
1128
WIN32LIB/SRCDEBUG/DRAWSHP.ASM
Normal file
1128
WIN32LIB/SRCDEBUG/DRAWSHP.ASM
Normal file
File diff suppressed because it is too large
Load Diff
257
WIN32LIB/SRCDEBUG/DS_DN.ASM
Normal file
257
WIN32LIB/SRCDEBUG/DS_DN.ASM
Normal file
@@ -0,0 +1,257 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_DN.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : September 6, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Draw_Normal -- Draws a normal row of pixels to the viewport *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Draw_Normal -- Draws a normal row of pixels to the viewport *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of pixels (not bytes) to draw *
|
||||
;* EDX = XTotal initializer value *
|
||||
;* ESI = shape (source) buffer address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = remaining bytes on the line *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to current location in the shape data *
|
||||
;* EDI - incr/decr by # pixels (not bytes) drawn/skipped *
|
||||
;* [WidthCount] - bytes remaining on the line *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit. *
|
||||
;* 08/09/1994 IML : Optimized for 32-bit. *
|
||||
;* 09/06/1994 IML : Integrated p_* and ds_* routines. *
|
||||
;*=========================================================================*
|
||||
PROC Draw_Normal NOLANGUAGE NEAR
|
||||
|
||||
mov [StashEDX],edx ; save edx
|
||||
mov edx,[Flags]
|
||||
mov eax,0 ; init to zero
|
||||
sub [WidthCount],ecx ; decrement bytes remaining by pixels
|
||||
; to draw
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Drawing Loop:
|
||||
; - Get a data byte
|
||||
; - If it's a 0, handle the run:
|
||||
; - get repetition value
|
||||
; - add it to EDI
|
||||
; - subtract it from [WidthCount]
|
||||
; - subtract it from ECX
|
||||
; - if ECX>0, draw again, else exit
|
||||
; - Otherwise:
|
||||
; - draw the pixel
|
||||
; - increment EDI to next pixel location
|
||||
; - decrement [WidthCount]
|
||||
; - loop until ECX is 0
|
||||
;--------------------------------------------------------------------
|
||||
test edx,SHAPE_EFFECTS ; are any effects flags set?
|
||||
jnz short ??general_draw_continue ; if so use the general purpose loop
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Extra fast draw loop for shapes with no flags set.
|
||||
;--------------------------------------------------------------------
|
||||
??fast_draw_loop:
|
||||
mov al,[esi] ; get a byte of the source
|
||||
inc esi
|
||||
or eax,eax ; is the byte a transparent run?
|
||||
jz short ??fast_is_run ; if yes then handle the run
|
||||
mov [edi],al ; store color value to viewport
|
||||
inc edi ; point to next viewport pixel
|
||||
dec ecx ; any source pixels left?
|
||||
jnz short ??fast_draw_loop ; if not then go home
|
||||
jmp ??out
|
||||
|
||||
??fast_is_run:
|
||||
mov al,[esi]
|
||||
inc esi
|
||||
add edi,eax ; move the viewport pointer
|
||||
sub ecx,eax ; chop down the width to do
|
||||
jg short ??fast_draw_loop ; while more to do, loop back up
|
||||
jmp ??out
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; General purpose draw loop for shapes with one or more flags set.
|
||||
;--------------------------------------------------------------------
|
||||
??general_draw_loop:
|
||||
test edx,SHAPE_FADING ; if fading is enabled test for
|
||||
jz short ??no_fading_draw_loop ; transparency
|
||||
or eax,eax
|
||||
jz short ??is_transparent
|
||||
|
||||
??no_fading_draw_loop:
|
||||
mov [edi],al ; store color value to viewport
|
||||
|
||||
??is_transparent:
|
||||
inc edi ; point to next viewport pixel
|
||||
dec ecx ; any source pixels left?
|
||||
jz ??out ; if not then go home
|
||||
|
||||
??general_draw_continue:
|
||||
mov al,[esi] ; get a byte of the source
|
||||
inc esi
|
||||
or eax,eax ; is the byte a transparent run?
|
||||
jz ??general_is_run ; if yes then handle the run
|
||||
|
||||
??test_priority:
|
||||
test edx,SHAPE_PRIORITY
|
||||
jnz short ??priority
|
||||
|
||||
??test_predator:
|
||||
test edx,SHAPE_PREDATOR
|
||||
jnz short ??predator
|
||||
|
||||
??test_compact:
|
||||
test edx,SHAPE_COMPACT
|
||||
jnz ??compact
|
||||
|
||||
??test_shadow:
|
||||
test edx,SHAPE_SHADOW
|
||||
jnz ??shadow
|
||||
|
||||
??test_translucency:
|
||||
test edx,SHAPE_GHOST
|
||||
jz short ??test_fading
|
||||
|
||||
mov ebx,[IsTranslucent] ; is it a translucent color?
|
||||
mov bh,[BYTE PTR ebx + eax]
|
||||
or bh,bh
|
||||
js short ??test_fading
|
||||
|
||||
and ebx,0FF00h ; clear all of ebx except bh
|
||||
; we have the index to the translation table
|
||||
; ((trans_colour * 256) + dest colour)
|
||||
mov al,[edi] ; mov pixel at destination to al
|
||||
add ebx,[Translucent] ; get the ptr to it!
|
||||
; Add the (trans_color * 256) of the translation equ.
|
||||
mov al,[BYTE PTR ebx + eax] ; get new pixel in al
|
||||
jmp short ??test_fading
|
||||
|
||||
??test_fading:
|
||||
test edx,SHAPE_FADING
|
||||
jnz ??fading
|
||||
jmp short ??general_draw_loop
|
||||
|
||||
??priority:
|
||||
mov ebx,[MaskAdjust] ; get mask page offset
|
||||
mov bl,[BYTE PTR ebx + edi] ; get mask value
|
||||
|
||||
and bl,CLEAR_UNUSED_BITS ; clear unused bits
|
||||
|
||||
cmp [PriLevel],bl ; are we in front of
|
||||
jge short ??test_predator ; background?
|
||||
|
||||
mov ebx,[BackAdjust] ; get background page offset
|
||||
mov al,[BYTE PTR ebx + edi] ; get background pixel
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??predator:
|
||||
mov ebx,[PartialCount]
|
||||
add ebx,[PartialPred]
|
||||
or bh,bh
|
||||
jnz short ??draw_pred ; is this a predator pixel?
|
||||
mov [PartialCount],ebx
|
||||
jmp short ??test_compact
|
||||
|
||||
??draw_pred:
|
||||
xor bh,bh
|
||||
mov [PartialCount],ebx
|
||||
mov ebx,[PredValue] ; pick up a color offset a pseudo-
|
||||
; random amount from the current
|
||||
mov al,[edi + ebx] ; viewport address
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??compact:
|
||||
mov ebx,[ColorTable] ; get the address of the color table
|
||||
mov al,[BYTE PTR ebx + eax] ; convert it into the proper byte
|
||||
jmp ??test_shadow
|
||||
|
||||
??shadow:
|
||||
cmp al,SHADOW_COL
|
||||
jne ??test_translucency ; is the table value a magic number?
|
||||
|
||||
mov al,[edi] ; get the destination color and
|
||||
mov ebx,[ShadowingTable] ; index into the shadow table
|
||||
mov al,[BYTE PTR ebx + eax]
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??fading:
|
||||
mov [StashECX],ecx ; preserve ecx for later
|
||||
mov ebx,[FadingTable] ; run color through fading table
|
||||
mov ecx,[FadingNum]
|
||||
|
||||
??fade_loop:
|
||||
mov al, [BYTE PTR ebx + eax]
|
||||
dec ecx
|
||||
jnz short ??fade_loop
|
||||
|
||||
mov ecx,[StashECX] ; restore ecx for main draw loop
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??general_is_run:
|
||||
mov al,[esi]
|
||||
inc esi
|
||||
add edi,eax ; move the viewport pointer
|
||||
sub ecx,eax ; chop down the width to do
|
||||
jg ??general_draw_continue ; while more to do, loop back up
|
||||
|
||||
??out:
|
||||
add [WidthCount],ecx ; adjust for source ending in a run
|
||||
mov edx,[StashEDX]
|
||||
ret
|
||||
|
||||
ENDP Draw_Normal
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_dn.asm *****************************
|
||||
257
WIN32LIB/SRCDEBUG/DS_DR.ASM
Normal file
257
WIN32LIB/SRCDEBUG/DS_DR.ASM
Normal file
@@ -0,0 +1,257 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_DR.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : September 6, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Draw_Reverse -- Draws a reversed row of pixels to the viewport *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Draw_Reverse -- Draws a reversed row of pixels to the viewport *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of pixels (not bytes) to draw *
|
||||
;* EDX = XTotal initializer value *
|
||||
;* ESI = shape (source) buffer address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = remaining bytes on the line *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to current location in the shape data *
|
||||
;* EDI - incr/decr by # pixels (not bytes) drawn/skipped *
|
||||
;* [WidthCount] - bytes remaining on the line *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit. *
|
||||
;* 08/09/1994 IML : Optimized for 32-bit. *
|
||||
;* 09/06/1994 IML : Integrated p_* and ds_* routines. *
|
||||
;*=========================================================================*
|
||||
PROC Draw_Reverse NOLANGUAGE NEAR
|
||||
|
||||
mov [StashEDX],edx ; save edx
|
||||
mov edx,[Flags]
|
||||
mov eax,0 ; init to zero
|
||||
sub [WidthCount],ecx ; decrement bytes remaining by pixels
|
||||
; to draw
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Drawing Loop:
|
||||
; - Get a data byte
|
||||
; - If it's a 0, handle the run:
|
||||
; - get repetition value
|
||||
; - subtract it from EDI
|
||||
; - subtract it from [WidthCount]
|
||||
; - subtract it from ECX
|
||||
; - if ECX>0, draw again, else exit
|
||||
; - Otherwise:
|
||||
; - draw the pixel
|
||||
; - increment EDI to next pixel location
|
||||
; - decrement [WidthCount]
|
||||
; - loop until ECX is 0
|
||||
;--------------------------------------------------------------------
|
||||
test edx,SHAPE_EFFECTS ; are any effects flags set?
|
||||
jnz short ??general_draw_continue ; if so use the general purpose loop
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Extra fast draw loop for shapes with no flags set.
|
||||
;--------------------------------------------------------------------
|
||||
??fast_draw_loop:
|
||||
mov al,[esi] ; get a byte of the source
|
||||
inc esi
|
||||
or eax,eax ; is the byte a transparent run?
|
||||
jz short ??fast_is_run ; if yes then handle the run
|
||||
mov [edi],al ; store color value to viewport
|
||||
dec edi ; point to next viewport pixel
|
||||
dec ecx ; any source pixels left?
|
||||
jnz short ??fast_draw_loop ; if not then go home
|
||||
jmp ??out
|
||||
|
||||
??fast_is_run:
|
||||
mov al,[esi]
|
||||
inc esi
|
||||
sub edi,eax ; move the viewport pointer
|
||||
sub ecx,eax ; chop down the width to do
|
||||
jg short ??fast_draw_loop ; while more to do, loop back up
|
||||
jmp ??out
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; General purpose draw loop for shapes with one or more flags set.
|
||||
;--------------------------------------------------------------------
|
||||
??general_draw_loop:
|
||||
test edx,SHAPE_FADING ; if fading is enabled test for
|
||||
jz short ??no_fading_draw_loop ; transparency
|
||||
or eax,eax
|
||||
jz short ??is_transparent
|
||||
|
||||
??no_fading_draw_loop:
|
||||
mov [edi],al ; store color value to viewport
|
||||
|
||||
??is_transparent:
|
||||
dec edi ; point to next viewport pixel
|
||||
dec ecx ; any source pixels left?
|
||||
jz ??out ; if not then go home
|
||||
|
||||
??general_draw_continue:
|
||||
mov al,[esi] ; get a byte of the source
|
||||
inc esi
|
||||
or eax,eax ; is the byte a transparent run?
|
||||
jz ??general_is_run ; if yes then handle the run
|
||||
|
||||
??test_priority:
|
||||
test edx,SHAPE_PRIORITY
|
||||
jnz short ??priority
|
||||
|
||||
??test_predator:
|
||||
test edx,SHAPE_PREDATOR
|
||||
jnz short ??predator
|
||||
|
||||
??test_compact:
|
||||
test edx,SHAPE_COMPACT
|
||||
jnz ??compact
|
||||
|
||||
??test_shadow:
|
||||
test edx,SHAPE_SHADOW
|
||||
jnz ??shadow
|
||||
|
||||
??test_translucency:
|
||||
test edx,SHAPE_GHOST
|
||||
jz short ??test_fading
|
||||
|
||||
mov ebx,[IsTranslucent] ; is it a translucent color?
|
||||
mov bh,[BYTE PTR ebx + eax]
|
||||
or bh,bh
|
||||
js short ??test_fading
|
||||
|
||||
and ebx,0FF00h ; clear all of ebx except bh
|
||||
; we have the index to the translation table
|
||||
; ((trans_colour * 256) + dest colour)
|
||||
mov al,[edi] ; mov pixel at destination to al
|
||||
add ebx,[Translucent] ; get the ptr to it!
|
||||
; Add the (trans_color * 256) of the translation equ.
|
||||
mov al,[BYTE PTR ebx + eax] ; get new pixel in al
|
||||
|
||||
??test_fading:
|
||||
test edx,SHAPE_FADING
|
||||
jnz ??fading
|
||||
jmp short ??general_draw_loop
|
||||
|
||||
??priority:
|
||||
mov ebx,[MaskAdjust] ; get mask page offset
|
||||
mov bl,[BYTE PTR ebx + edi] ; get mask value
|
||||
|
||||
and bl,CLEAR_UNUSED_BITS ; clear unused bits
|
||||
|
||||
cmp [PriLevel],bl ; are we in front of
|
||||
jge short ??test_predator ; background?
|
||||
|
||||
mov ebx,[BackAdjust] ; get background page offset
|
||||
mov al,[BYTE PTR ebx + edi] ; get background pixel
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??predator:
|
||||
mov ebx,[PartialCount]
|
||||
add ebx,[PartialPred]
|
||||
or bh,bh
|
||||
jnz short ??draw_pred ; is this a predator pixel?
|
||||
mov [PartialCount],ebx
|
||||
jmp short ??test_compact
|
||||
|
||||
??draw_pred:
|
||||
xor bh,bh
|
||||
mov [PartialCount],ebx
|
||||
mov ebx,[PredValue] ; pick up a color offset a pseudo-
|
||||
; random amount from the current
|
||||
mov al,[edi + ebx] ; viewport address
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??compact:
|
||||
mov ebx,[ColorTable] ; get the address of the color table
|
||||
mov al,[BYTE PTR ebx + eax] ; convert it into the proper byte
|
||||
jmp ??test_shadow
|
||||
|
||||
??shadow:
|
||||
cmp al,SHADOW_COL
|
||||
jne ??test_translucency ; is the table value a magic number?
|
||||
|
||||
mov al,[edi] ; get the destination color and
|
||||
mov ebx,[ShadowingTable] ; index into the shadow table
|
||||
mov al,[BYTE PTR ebx + eax]
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??fading:
|
||||
mov [StashECX],ecx ; preserve ecx for later
|
||||
mov ebx,[FadingTable] ; run color through fading table
|
||||
mov ecx,[FadingNum]
|
||||
|
||||
??fade_loop:
|
||||
mov al, [BYTE PTR ebx + eax]
|
||||
dec ecx
|
||||
jnz short ??fade_loop
|
||||
|
||||
mov ecx,[StashECX] ; restore ecx for main draw loop
|
||||
jmp ??general_draw_loop
|
||||
|
||||
??general_is_run:
|
||||
mov al,[esi]
|
||||
inc esi
|
||||
sub edi,eax ; move the viewport pointer
|
||||
sub ecx,eax ; chop down the width to do
|
||||
jg ??general_draw_continue ; while more to do, loop back up
|
||||
|
||||
??out:
|
||||
add [WidthCount],ecx ; adjust for source ending in a run
|
||||
mov edx,[StashEDX]
|
||||
ret
|
||||
|
||||
ENDP Draw_Reverse
|
||||
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_dr.asm *****************************
|
||||
341
WIN32LIB/SRCDEBUG/DS_DS.ASM
Normal file
341
WIN32LIB/SRCDEBUG/DS_DS.ASM
Normal file
@@ -0,0 +1,341 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_DS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : September 6, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Draw_Scale -- Draws a scaled row of pixels to the viewport *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Draw_Scale -- Draws a scaled row of pixels to the viewport *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of pixels (not bytes) to draw *
|
||||
;* EDX = XTotal initializer value *
|
||||
;* ESI = shape (source) buffer address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = remaining bytes on the line *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to current location in the shape data *
|
||||
;* EDI - incr/decr by # pixels (not bytes) drawn/skipped *
|
||||
;* [WidthCount] - bytes remaining on the line *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit. *
|
||||
;* 08/09/1994 IML : Optimized for 32-bit. *
|
||||
;* 09/06/1994 IML : Integrated p_* and ds_* routines. *
|
||||
;*=========================================================================*
|
||||
PROC Draw_Scale NOLANGUAGE NEAR
|
||||
|
||||
mov eax,0 ; init to 0
|
||||
test [Flags],SHAPE_EFFECTS
|
||||
jnz short ??general_draw_continue
|
||||
jmp short ??fast_draw_continue
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Extra fast draw loop for shapes with no flags set.
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Load a new byte:
|
||||
; - read the byte into AL
|
||||
; - if it's a run, deal with it
|
||||
; - otherwise,
|
||||
; - decrement [WidthCount]
|
||||
; - update EDX with [ScaleX]
|
||||
; - see if it's drawable (upon proc entry, it won't be)
|
||||
; - yes: draw a pixel
|
||||
; - no : load a new byte
|
||||
;--------------------------------------------------------------------
|
||||
??fast_draw_loop:
|
||||
mov al,[esi] ; get the next pixel from the source
|
||||
inc esi
|
||||
or eax,eax
|
||||
jz short ??fast_is_run ; deal with a run
|
||||
dec [WidthCount] ; count down # bytes processed
|
||||
add edx,[ScaleX] ; add in the scale value
|
||||
|
||||
??fast_draw_continue:
|
||||
or dh,dh ; are there any pixels to draw?
|
||||
jz short ??fast_draw_loop
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Draw one pixel:
|
||||
; - draw the pixel
|
||||
; - increment destination pointer
|
||||
; - decrement high byte of EDX (X-scale accumulator)
|
||||
; - loop (while ECX>0) to see if it's drawable
|
||||
;--------------------------------------------------------------------
|
||||
mov [edi],al ; store color value to viewport
|
||||
inc edi ; increment the destination index
|
||||
dec dh ; decrement the pixels to write
|
||||
dec ecx
|
||||
jnz short ??fast_draw_continue
|
||||
jmp ??out ; get the heck outta here
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Handle a run:
|
||||
; - Get the run repetition value
|
||||
; - subract it from [WidthCount]
|
||||
; - multiply it by [ScaleX]
|
||||
; - put high bytes from mul into EAX, low byte into DL (roundoff bits)
|
||||
; - add high bytes (# pixels) to EDI
|
||||
; - subtract them from ECX
|
||||
; - clear EAX
|
||||
; - if ECX>0, go get next byte
|
||||
;--------------------------------------------------------------------
|
||||
??fast_is_run:
|
||||
mov al,[esi] ; get number of repeated values
|
||||
inc esi
|
||||
sub [WidthCount],eax ; adjust the remaining byte width
|
||||
mov ebx,edx ; preserve dx for the multiply
|
||||
mul [ScaleX] ; EDX:EAX = # pixels + roundoff bits
|
||||
add eax,ebx ; add in the current x-total
|
||||
mov edx,eax ; (assume EDX is empty)
|
||||
shr eax,8 ; EAX = # pixels skipped
|
||||
and edx,00FFh ; keep only low byte
|
||||
add edi,eax ; add to EDI
|
||||
sub ecx,eax ; subtract it from ECX
|
||||
mov eax,0 ; clear EAX
|
||||
or ecx,ecx
|
||||
jg short ??fast_draw_loop ; if more to draw, process new byte
|
||||
jmp ??out
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; General purpose draw loop for shapes with one or more flags set.
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Load a new byte:
|
||||
; - read the byte into AL
|
||||
; - if it's a run, deal with it
|
||||
; - otherwise,
|
||||
; - decrement [WidthCount]
|
||||
; - update EDX with [ScaleX]
|
||||
; - see if it's drawable (upon proc entry, it won't be)
|
||||
; - yes: draw a pixel
|
||||
; - no : load a new byte
|
||||
;--------------------------------------------------------------------
|
||||
??general_draw_loop:
|
||||
mov al,[esi] ; get the next pixel from the source
|
||||
inc esi
|
||||
or eax,eax
|
||||
jz ??general_is_run ; deal with a run
|
||||
dec [WidthCount] ; count down # bytes processed
|
||||
add edx,[ScaleX] ; add in the scale value
|
||||
|
||||
??general_draw_continue:
|
||||
or dh,dh ; are there any pixels to draw?
|
||||
jz short ??general_draw_loop
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Draw one pixel:
|
||||
; - draw the pixel
|
||||
; - increment destination pointer
|
||||
; - decrement high byte of EDX (X-scale accumulator)
|
||||
; - loop (while ECX>0) to see if it's drawable
|
||||
;--------------------------------------------------------------------
|
||||
??draw:
|
||||
mov [StashReg],eax ; save eax
|
||||
mov [StashEDX],edx ; save edx
|
||||
mov edx,[Flags]
|
||||
|
||||
??test_priority:
|
||||
test edx,SHAPE_PRIORITY
|
||||
jnz short ??priority
|
||||
|
||||
??test_predator:
|
||||
test edx,SHAPE_PREDATOR
|
||||
jnz short ??predator
|
||||
|
||||
??test_compact:
|
||||
test edx,SHAPE_COMPACT
|
||||
jnz ??compact
|
||||
|
||||
??test_shadow:
|
||||
test edx,SHAPE_SHADOW
|
||||
jnz ??shadow
|
||||
|
||||
??test_translucency:
|
||||
test edx,SHAPE_GHOST
|
||||
jnz ??translucency
|
||||
|
||||
??test_fading:
|
||||
test edx,SHAPE_FADING
|
||||
jnz ??fading
|
||||
|
||||
|
||||
??test_transparency:
|
||||
test edx,SHAPE_FADING ; if fading is enabled test for
|
||||
jz short ??no_fading_draw_loop ; transparency
|
||||
or eax,eax
|
||||
jz short ??is_transparent
|
||||
|
||||
??no_fading_draw_loop:
|
||||
mov [edi],al ; store color value to viewport
|
||||
|
||||
??is_transparent:
|
||||
mov eax,[StashReg] ; restore eax
|
||||
mov edx,[StashEDX] ; restore edx
|
||||
inc edi ; increment the destination index
|
||||
dec dh ; decrement the pixels to write
|
||||
dec ecx
|
||||
jnz ??general_draw_continue
|
||||
jmp ??out ; get the heck outta here
|
||||
|
||||
??priority:
|
||||
mov ebx,[MaskAdjust] ; get mask page offset
|
||||
mov bl,[BYTE PTR ebx + edi] ; get mask value
|
||||
|
||||
and bl,CLEAR_UNUSED_BITS ; clear unused bits
|
||||
|
||||
cmp [PriLevel],bl ; are we in front of
|
||||
jge short ??test_predator ; background?
|
||||
|
||||
mov ebx,[BackAdjust] ; get background page offset
|
||||
mov al,[BYTE PTR ebx + edi] ; get background pixel
|
||||
jmp short ??test_transparency
|
||||
|
||||
??predator:
|
||||
mov ebx,[PartialCount]
|
||||
add ebx,[PartialPred]
|
||||
or bh,bh
|
||||
jnz short ??draw_pred ; is this a predator pixel?
|
||||
mov [PartialCount],ebx
|
||||
jmp ??test_compact
|
||||
|
||||
??draw_pred:
|
||||
xor bh,bh
|
||||
mov [PartialCount],ebx
|
||||
mov ebx,[PredValue] ; pick up a color offset a pseudo-
|
||||
; random amount from the current
|
||||
mov al,[edi + ebx] ; viewport address
|
||||
jmp short ??test_transparency
|
||||
|
||||
??compact:
|
||||
mov ebx,[ColorTable] ; get the address of the color table
|
||||
mov al,[BYTE PTR ebx + eax] ; convert it into the proper byte
|
||||
jmp ??test_shadow
|
||||
|
||||
??shadow:
|
||||
cmp al,SHADOW_COL
|
||||
jne ??test_translucency ; is the table value a magic number?
|
||||
|
||||
mov al,[edi] ; get the destination color and
|
||||
mov ebx,[ShadowingTable] ; index into the shadow table
|
||||
mov al,[BYTE PTR ebx + eax]
|
||||
jmp ??test_transparency
|
||||
|
||||
??fading:
|
||||
mov [StashECX],ecx ; preserve ecx for later
|
||||
mov ebx,[FadingTable] ; run color through fading table
|
||||
mov ecx,[FadingNum]
|
||||
|
||||
??fade_loop:
|
||||
mov al, [BYTE PTR ebx + eax]
|
||||
dec ecx
|
||||
jnz short ??fade_loop
|
||||
|
||||
mov ecx,[StashECX] ; restore ecx for main draw loop
|
||||
jmp ??test_transparency
|
||||
|
||||
??translucency:
|
||||
mov ebx,[IsTranslucent] ; is it a translucent color?
|
||||
mov bh,[BYTE PTR ebx + eax]
|
||||
or bh,bh
|
||||
js ??test_fading
|
||||
|
||||
and ebx,0FF00h ; clear all of ebx except bh
|
||||
; we have the index to the translation table
|
||||
; ((trans_colour * 256) + dest colour)
|
||||
mov al,[edi] ; mov pixel at destination to al
|
||||
add ebx,[Translucent] ; get the ptr to it!
|
||||
; Add the (trans_color * 256) of the translation equ.
|
||||
mov al,[BYTE PTR ebx + eax] ; get new pixel in al
|
||||
jmp ??test_fading
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Handle a run:
|
||||
; - Get the run repetition value
|
||||
; - subract it from [WidthCount]
|
||||
; - multiply it by [ScaleX]
|
||||
; - put high bytes from mul into EAX, low byte into DL (roundoff bits)
|
||||
; - add high bytes (# pixels) to EDI
|
||||
; - subtract them from ECX
|
||||
; - clear EAX
|
||||
; - if ECX>0, go get next byte
|
||||
;--------------------------------------------------------------------
|
||||
??general_is_run:
|
||||
mov al,[esi] ; get number of repeated values
|
||||
inc esi
|
||||
sub [WidthCount],eax ; adjust the remaining byte width
|
||||
mov ebx,edx ; preserve dx for the multiply
|
||||
mul [ScaleX] ; EDX:EAX = # pixels + roundoff bits
|
||||
add eax,ebx ; add in the current x-total
|
||||
mov edx,eax ; (assume EDX is empty)
|
||||
shr eax,8 ; EAX = # pixels skipped
|
||||
and edx,00FFh ; keep only low byte
|
||||
add edi,eax ; add to EDI
|
||||
sub ecx,eax ; subtract it from ECX
|
||||
mov eax,0 ; clear EAX
|
||||
or ecx,ecx
|
||||
jg ??general_draw_loop ; if more to draw, process new byte
|
||||
|
||||
??out:
|
||||
ret ; lets get out of here
|
||||
|
||||
ENDP Draw_Scale
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_ds.asm ******************************
|
||||
341
WIN32LIB/SRCDEBUG/DS_DSR.ASM
Normal file
341
WIN32LIB/SRCDEBUG/DS_DSR.ASM
Normal file
@@ -0,0 +1,341 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_DSR.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : September 6, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Draw_Scale_Reverse -- Draws a scaled row of pixels to the viewport *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;*******p********************************************************************
|
||||
;* Draw_Scale_Reverse -- Draws a scaled row of pixels to the viewport *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of pixels (not bytes) to draw *
|
||||
;* EDX = XTotal initializer value *
|
||||
;* ESI = shape (source) buffer address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = remaining bytes on the line *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to current location in the shape data *
|
||||
;* EDI - incr/decr by # pixels (not bytes) drawn/skipped *
|
||||
;* [WidthCount] - bytes remaining on the line *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit. *
|
||||
;* 08/09/1994 IML : Optimized for 32-bit *
|
||||
;* 09/06/1994 IML : Integrated p_* and ds_* routines. *
|
||||
;*=========================================================================*
|
||||
PROC Draw_Scale_Reverse NOLANGUAGE NEAR
|
||||
|
||||
mov eax,0 ; init to 0
|
||||
test [Flags],SHAPE_EFFECTS
|
||||
jnz short ??general_draw_continue
|
||||
jmp short ??fast_draw_continue
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Extra fast draw loop for shapes with no flags set.
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Load a new byte:
|
||||
; - read the byte into AL
|
||||
; - if it's a run, deal with it
|
||||
; - otherwise,
|
||||
; - decrement [WidthCount]
|
||||
; - update EDX with [ScaleX]
|
||||
; - see if it's drawable (upon proc entry, it won't be)
|
||||
; - yes: draw a pixel
|
||||
; - no : load a new byte
|
||||
;--------------------------------------------------------------------
|
||||
??fast_draw_loop:
|
||||
mov al,[esi] ; get the next pixel from the source
|
||||
inc esi
|
||||
or eax,eax
|
||||
jz short ??fast_is_run ; deal with a run
|
||||
dec [WidthCount] ; count down # bytes processed
|
||||
add edx,[ScaleX] ; add in the scale value
|
||||
|
||||
??fast_draw_continue:
|
||||
or dh,dh ; are there any pixels to draw?
|
||||
jz short ??fast_draw_loop
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Draw one pixel:
|
||||
; - draw the pixel
|
||||
; - increment destination pointer
|
||||
; - decrement high byte of EDX (X-scale accumulator)
|
||||
; - loop (while ECX>0) to see if it's drawable
|
||||
;--------------------------------------------------------------------
|
||||
mov [edi],al ; store color value to viewport
|
||||
dec edi ; decrement the destination index
|
||||
dec dh ; decrement the pixels to write
|
||||
dec ecx
|
||||
jnz short ??fast_draw_continue
|
||||
jmp ??out ; get the heck outta here
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Handle a run:
|
||||
; - Get the run repetition value
|
||||
; - subract it from [WidthCount]
|
||||
; - multiply it by [ScaleX]
|
||||
; - put high bytes from mul into EAX, low byte into DL (roundoff bits)
|
||||
; - add high bytes (# pixels) to EDI
|
||||
; - subtract them from ECX
|
||||
; - clear EAX
|
||||
; - if ECX>0, go get next byte
|
||||
;--------------------------------------------------------------------
|
||||
??fast_is_run:
|
||||
mov al,[esi] ; get number of repeated values
|
||||
inc esi
|
||||
sub [WidthCount],eax ; adjust the remaining byte width
|
||||
mov ebx,edx ; preserve dx for the multiply
|
||||
mul [ScaleX] ; EDX:EAX = # pixels + roundoff bits
|
||||
add eax,ebx ; add in the current x-total
|
||||
mov edx,eax ; (assume EDX is empty)
|
||||
shr eax,8 ; EAX = # pixels skipped
|
||||
and edx,00FFh ; keep only low byte
|
||||
sub edi,eax ; sub from EDI
|
||||
sub ecx,eax ; subtract it from ECX
|
||||
mov eax,0 ; clear EAX
|
||||
or ecx,ecx
|
||||
jg short ??fast_draw_loop ; if more to draw, process new byte
|
||||
jmp ??out
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; General purpose draw loop for shapes with one or more flags set.
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Load a new byte:
|
||||
; - read the byte into AL
|
||||
; - if it's a run, deal with it
|
||||
; - otherwise,
|
||||
; - decrement [WidthCount]
|
||||
; - update EDX with [ScaleX]
|
||||
; - see if it's drawable (upon proc entry, it won't be)
|
||||
; - yes: draw a pixel
|
||||
; - no : load a new byte
|
||||
;--------------------------------------------------------------------
|
||||
??general_draw_loop:
|
||||
mov al,[esi] ; get the next pixel from the source
|
||||
inc esi
|
||||
or eax,eax
|
||||
jz ??general_is_run ; deal with a run
|
||||
dec [WidthCount] ; count down # bytes processed
|
||||
add edx,[ScaleX] ; add in the scale value
|
||||
|
||||
??general_draw_continue:
|
||||
or dh,dh ; are there any pixels to draw?
|
||||
jz short ??general_draw_loop
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Draw one pixel:
|
||||
; - draw the pixel
|
||||
; - increment destination pointer
|
||||
; - decrement high byte of EDX (X-scale accumulator)
|
||||
; - loop (while ECX>0) to see if it's drawable
|
||||
;--------------------------------------------------------------------
|
||||
??draw:
|
||||
mov [StashReg],eax ; save eax
|
||||
mov [StashEDX],edx ; save edx
|
||||
mov edx,[Flags]
|
||||
|
||||
??test_priority:
|
||||
test edx,SHAPE_PRIORITY
|
||||
jnz short ??priority
|
||||
|
||||
??test_predator:
|
||||
test edx,SHAPE_PREDATOR
|
||||
jnz short ??predator
|
||||
|
||||
??test_compact:
|
||||
test edx,SHAPE_COMPACT
|
||||
jnz ??compact
|
||||
|
||||
??test_shadow:
|
||||
test edx,SHAPE_SHADOW
|
||||
jnz ??shadow
|
||||
|
||||
??test_translucency:
|
||||
test edx,SHAPE_GHOST
|
||||
jnz ??translucency
|
||||
|
||||
??test_fading:
|
||||
test edx,SHAPE_FADING
|
||||
jnz ??fading
|
||||
|
||||
??test_transparency:
|
||||
test edx,SHAPE_FADING ; if fading is enabled test for
|
||||
jz short ??no_fading_draw_loop ; transparency
|
||||
or eax,eax
|
||||
jz short ??is_transparent
|
||||
|
||||
??no_fading_draw_loop:
|
||||
mov [edi],al ; store color value to viewport
|
||||
|
||||
??is_transparent:
|
||||
mov eax,[StashReg] ; restore eax
|
||||
mov edx,[StashEDX] ; restore edx
|
||||
dec edi ; decrement the destination index
|
||||
dec dh ; decrement the pixels to write
|
||||
dec ecx
|
||||
jnz ??general_draw_continue
|
||||
jmp ??out ; get the heck outta here
|
||||
|
||||
??priority:
|
||||
mov ebx,[MaskAdjust] ; get mask page offset
|
||||
mov bl,[BYTE PTR ebx + edi] ; get mask value
|
||||
|
||||
and bl,CLEAR_UNUSED_BITS ; clear unused bits
|
||||
|
||||
cmp [PriLevel],bl ; are we in front of
|
||||
jge short ??test_predator ; background?
|
||||
|
||||
mov ebx,[BackAdjust] ; get background page offset
|
||||
mov al,[BYTE PTR ebx + edi] ; get background pixel
|
||||
jmp short ??test_transparency
|
||||
|
||||
??predator:
|
||||
mov ebx,[PartialCount]
|
||||
add ebx,[PartialPred]
|
||||
or bh,bh
|
||||
jnz short ??draw_pred ; is this a predator pixel?
|
||||
mov [PartialCount],ebx
|
||||
jmp ??test_compact
|
||||
|
||||
??draw_pred:
|
||||
xor bh,bh
|
||||
mov [PartialCount],ebx
|
||||
mov ebx,[PredValue] ; pick up a color offset a pseudo-
|
||||
; random amount from the current
|
||||
mov al,[edi + ebx] ; viewport address
|
||||
jmp short ??test_transparency
|
||||
|
||||
??compact:
|
||||
mov ebx,[ColorTable] ; get the address of the color table
|
||||
mov al,[BYTE PTR ebx + eax] ; convert it into the proper byte
|
||||
jmp ??test_shadow
|
||||
|
||||
??shadow:
|
||||
cmp al,SHADOW_COL
|
||||
jne ??test_translucency ; is the table value a magic number?
|
||||
|
||||
mov al,[edi] ; get the destination color and
|
||||
mov ebx,[ShadowingTable] ; index into the shadow table
|
||||
mov al,[BYTE PTR ebx + eax]
|
||||
jmp ??test_transparency
|
||||
|
||||
??fading:
|
||||
mov [StashECX],ecx ; preserve ecx for later
|
||||
mov ebx,[FadingTable] ; run color through fading table
|
||||
mov ecx,[FadingNum]
|
||||
|
||||
??fade_loop:
|
||||
mov al, [BYTE PTR ebx + eax]
|
||||
dec ecx
|
||||
jnz short ??fade_loop
|
||||
|
||||
mov ecx,[StashECX] ; restore ecx for main draw loop
|
||||
jmp ??test_transparency
|
||||
|
||||
??translucency:
|
||||
mov ebx,[IsTranslucent] ; is it a translucent color?
|
||||
mov bh,[BYTE PTR ebx + eax]
|
||||
or bh,bh
|
||||
js ??test_fading
|
||||
|
||||
and ebx,0FF00h ; clear all of ebx except bh
|
||||
; we have the index to the translation table
|
||||
; ((trans_colour * 256) + dest colour)
|
||||
mov al,[edi] ; mov pixel at destination to al
|
||||
add ebx,[Translucent] ; get the ptr to it!
|
||||
; Add the (trans_color * 256) of the translation equ.
|
||||
mov al,[BYTE PTR ebx + eax] ; get new pixel in al
|
||||
jmp ??test_fading
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Handle a run:
|
||||
; - Get the run repetition value
|
||||
; - subract it from [WidthCount]
|
||||
; - multiply it by [ScaleX]
|
||||
; - put high bytes from mul into EAX, low byte into DL (roundoff bits)
|
||||
; - add high bytes (# pixels) to EDI
|
||||
; - subtract them from ECX
|
||||
; - clear EAX
|
||||
; - if ECX>0, go get next byte
|
||||
;--------------------------------------------------------------------
|
||||
??general_is_run:
|
||||
mov al,[esi] ; get number of repeated values
|
||||
inc esi
|
||||
sub [WidthCount],eax ; adjust the remaining byte width
|
||||
mov ebx,edx ; preserve dx for the multiply
|
||||
mul [ScaleX] ; EDX:EAX = # pixels + roundoff bits
|
||||
add eax,ebx ; add in the current x-total
|
||||
mov edx,eax ; (assume EDX is empty)
|
||||
shr eax,8 ; EAX = # pixels skipped
|
||||
and edx,00FFh ; keep only low byte
|
||||
sub edi,eax ; sub from EDI
|
||||
sub ecx,eax ; subtract it from ECX
|
||||
mov eax,0 ; clear EAX
|
||||
or ecx,ecx
|
||||
jg ??general_draw_loop ; if more to draw, process new byte
|
||||
|
||||
??out:
|
||||
ret ; lets get out of here
|
||||
|
||||
|
||||
ENDP Draw_Scale_Reverse
|
||||
|
||||
END
|
||||
|
||||
;*************************** End of ds_dsr.asm ******************************
|
||||
118
WIN32LIB/SRCDEBUG/DS_LRS.ASM
Normal file
118
WIN32LIB/SRCDEBUG/DS_LRS.ASM
Normal file
@@ -0,0 +1,118 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_LRS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : June 2, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Left_Reverse_Skip -- Skips bytes in a data stream *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Left_Reverse_Skip -- Skips bytes in a data stream *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape (source) buffer data address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = shape's width *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ECX - negative # pixels overrun, or 0 *
|
||||
;* EDX - XTotal initializer value (0 since there's no scaling)*
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* EDI - decremented by # pixels overrun *
|
||||
;* [WidthCount] - decremented by # bytes skipped *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 05/28/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Left_Reverse_Skip NOLANGUAGE NEAR
|
||||
|
||||
sub [WidthCount],ecx ; we process ECX bytes of real width
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jecxz ??out ; exit if ECX is 0 (no bytes to skip)
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz ??on_run ; if it is a run then deal with it
|
||||
jecxz ??out ; if we're done then get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
add edi,ecx ; decrement EDI by overrun pixels
|
||||
add [WidthCount],ecx ; adjust by # bytes overrun
|
||||
mov edx,0 ; no scaling, so clear EDX
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Left_Reverse_Skip
|
||||
|
||||
END
|
||||
|
||||
;*************************** End of ds_lrs.asm *****************************
|
||||
|
||||
118
WIN32LIB/SRCDEBUG/DS_LS.ASM
Normal file
118
WIN32LIB/SRCDEBUG/DS_LS.ASM
Normal file
@@ -0,0 +1,118 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_LS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : June 2, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Left_Skip -- Skips bytes in a data stream *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Left_Skip -- Skips bytes in a data stream *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape (source) buffer data address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = shape's width *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ECX - negative # pixels overrun, or 0 *
|
||||
;* EDX - XTotal initializer value (0 since there's no scaling)*
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* EDI - incremented by # pixels overrun *
|
||||
;* [WidthCount] - decremented by # bytes skipped *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Left_Skip NOLANGUAGE NEAR
|
||||
|
||||
sub [WidthCount],ecx ; we process ECX bytes of real width
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jecxz ??out ; exit if ECX is 0 (no bytes to skip)
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz ??on_run ; if it is a run then deal with it
|
||||
jecxz ??out ; if we're done then get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
sub edi,ecx ; increment EDI by overrun pixels
|
||||
add [WidthCount],ecx ; adjust by # bytes overrun
|
||||
mov edx,0 ; no scaling, so clear EDX
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Left_Skip
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_ls.asm *****************************
|
||||
|
||||
159
WIN32LIB/SRCDEBUG/DS_LSRS.ASM
Normal file
159
WIN32LIB/SRCDEBUG/DS_LSRS.ASM
Normal file
@@ -0,0 +1,159 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_LSRS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : June 2, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Left_Scale_Reverse_Skip -- Skips past a scaled row of pixels *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Left_Scale_Reverse_Skip -- Skips past a scaled row of pixels *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape (source) buffer data address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = shape's width *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ECX - negative # pixels (not bytes) overrun, or 0 *
|
||||
;* EDX - XTotal initializer value *
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* EDI - decremented by # pixels (not bytes) overrun *
|
||||
;* [WidthCount] - decremented by # bytes skipped *
|
||||
;* *
|
||||
;* The value returned in EDX reflects what XTotal's accumulated value *
|
||||
;* should be at the new pixel location. If no bytes are overrun, this *
|
||||
;* will be whatever is stored in [XTotalInit] (which will be 0 if no *
|
||||
;* pixels are left-clipped). *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/20/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Left_Scale_Reverse_Skip NOLANGUAGE NEAR
|
||||
|
||||
sub [WidthCount],ecx ; we process ECX bytes of real width
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jcxz ??getrem ; exit if no bytes to skip
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz short ??on_run ; if it is a run then deal with it
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Default exit point: store default x-scale bits & exit
|
||||
;--------------------------------------------------------------------
|
||||
??getrem:
|
||||
mov edx,[XTotalInit] ; store out the remainder
|
||||
jmp short ??out ; we're done, get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
jz ??getrem ; exactly enough bytes; exit
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Overrun exit point: ECX is negative by the # of bytes overrun.
|
||||
; - adjust [WidthCount] by # of overrun bytes
|
||||
; - compute the remainder at the new location (EDX)
|
||||
; - compute the number of destination pixels to skip (ECX)
|
||||
; - adjust EDI by # of overrun bytes
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
;............... adjust [WidthCount] by overrun bytes ...............
|
||||
;
|
||||
add [WidthCount],ecx ; adjust overrun in bytes
|
||||
;
|
||||
;................. put x-scale roundoff bits in EDX .................
|
||||
;
|
||||
mov eax,ecx ; get the number of bytes we overran
|
||||
neg eax ; negate it since overun is negative
|
||||
add eax,[LeftClipBytes] ; add the number of bytes we leftclip
|
||||
mul [ScaleX] ; convert to pixels plus roundoff bits
|
||||
mov edx,0 ; clear EDX
|
||||
mov dl,al ; DL = x-scaling roundoff bits
|
||||
;
|
||||
;................ put negative overrun pixels in ECX ................
|
||||
;
|
||||
shr eax,8 ; EAX = total # left pixels
|
||||
sub eax,[LeftClipPixels] ; EAX = # pixels overrun
|
||||
mov ecx,eax ; store # overrun pixels
|
||||
neg ecx ; make it negative
|
||||
;
|
||||
;................ adjust dest ptr by overrun pixels .................
|
||||
;
|
||||
sub esi,eax ; decrement ESI (EDI) by overrun pixels
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Left_Scale_Reverse_Skip
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_lsrs.asm ****************************
|
||||
|
||||
159
WIN32LIB/SRCDEBUG/DS_LSS.ASM
Normal file
159
WIN32LIB/SRCDEBUG/DS_LSS.ASM
Normal file
@@ -0,0 +1,159 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_LSS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : June 2, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Left_Scale_Skip -- Skips past a scaled row of pixels on left side *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Left_Scale_Skip -- Skips past a scaled row of pixels on left side *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape (source) buffer data address *
|
||||
;* EDI = viewport (destination) address *
|
||||
;* [WidthCount] = shape's width *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ECX - negative # pixels (not bytes) overrun, or 0 *
|
||||
;* EDX - XTotal initializer value *
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* EDI - incremented by # pixels (not bytes) overrun *
|
||||
;* [WidthCount] - decremented by # bytes skipped *
|
||||
;* *
|
||||
;* The value returned in EDX reflects what XTotal's accumulated value *
|
||||
;* should be at the new pixel location. If no bytes are overrun, this *
|
||||
;* will be whatever is stored in [XTotalInit] (which will be 0 if no *
|
||||
;* pixels are left-clipped). *
|
||||
;* *
|
||||
;* WARNINGS: none *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 09/08/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/02/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Left_Scale_Skip NOLANGUAGE NEAR
|
||||
|
||||
sub [WidthCount],ecx ; we process ECX bytes of real width
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jcxz ??getrem ; exit if no bytes to skip
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz short ??on_run ; if it is a run then deal with it
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Default exit point: store default x-scale bits & exit
|
||||
;--------------------------------------------------------------------
|
||||
??getrem:
|
||||
mov edx,[XTotalInit] ; store out the remainder
|
||||
jmp short ??out ; we're done, get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
jz ??getrem ; exactly enough bytes; exit
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Overrun exit point: ECX is negative by the # of bytes overrun.
|
||||
; - adjust [WidthCount] by # of overrun bytes
|
||||
; - compute the remainder at the new location (EDX)
|
||||
; - compute the number of destination pixels to skip (ECX)
|
||||
; - adjust EDI by # of overrun bytes
|
||||
;--------------------------------------------------------------------
|
||||
;
|
||||
;............... adjust [WidthCount] by overrun bytes ...............
|
||||
;
|
||||
add [WidthCount],ecx ; adjust overrun in bytes
|
||||
;
|
||||
;................. put x-scale roundoff bits in EDX .................
|
||||
;
|
||||
mov eax,ecx ; get the number of bytes we overran
|
||||
neg eax ; negate it since overun is negative
|
||||
add eax,[LeftClipBytes] ; add the number of bytes we leftclip
|
||||
mul [ScaleX] ; convert to pixels plus roundoff bits
|
||||
mov edx,0 ; clear EDX
|
||||
mov dl,al ; DL = x-scaling roundoff bits
|
||||
;
|
||||
;................ put negative overrun pixels in ECX ................
|
||||
;
|
||||
shr eax,8 ; EAX = total # left pixels
|
||||
sub eax,[LeftClipPixels] ; EAX = # pixels overrun
|
||||
mov ecx,eax ; store # overrun pixels
|
||||
neg ecx ; make it negative
|
||||
;
|
||||
;................ adjust dest ptr by overrun pixels .................
|
||||
;
|
||||
add esi,eax ; increment ESI (EDI) by overrun pixels
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Left_Scale_Skip
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_lss.asm *****************************
|
||||
|
||||
110
WIN32LIB/SRCDEBUG/DS_RRS.ASM
Normal file
110
WIN32LIB/SRCDEBUG/DS_RRS.ASM
Normal file
@@ -0,0 +1,110 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_RRS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : May 28, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Right_Reverse_Skip -- Skips bytes in a data stream *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Right_Reverse_Skip -- Skips bytes in a data stream *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape buffer data address *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* *
|
||||
;* WARNINGS: This routine may overrun the number of requested bytes *
|
||||
;* if it encounters a run of 0's; however, it's assumed that *
|
||||
;* the shape data will never contain a run that goes past the *
|
||||
;* right-hand edge of the shape. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 05/28/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Right_Reverse_Skip NOLANGUAGE NEAR
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jecxz ??out ; exit if ECX is 0 (no bytes to skip)
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz ??on_run ; if it is a run then deal with it
|
||||
jecxz ??out ; if we're done then get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Right_Reverse_Skip
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_rrs.asm ****************************
|
||||
|
||||
110
WIN32LIB/SRCDEBUG/DS_RS.ASM
Normal file
110
WIN32LIB/SRCDEBUG/DS_RS.ASM
Normal file
@@ -0,0 +1,110 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_RS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : May 28, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Right_Skip -- Skips bytes in a data stream *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Right_Skip -- Skips bytes in a data stream *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape buffer data address *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* *
|
||||
;* WARNINGS: This routine may overrun the number of requested bytes *
|
||||
;* if it encounters a run of 0's; however, it's assumed that *
|
||||
;* the shape data will never contain a run that goes past the *
|
||||
;* right-hand edge of the shape. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/14/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 05/28/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Right_Skip NOLANGUAGE NEAR
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jecxz ??out ; exit if ECX is 0 (no bytes to skip)
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz ??on_run ; if it is a run then deal with it
|
||||
jecxz ??out ; if we're done then get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Right_Skip
|
||||
|
||||
END
|
||||
|
||||
;**************************** End of ds_rs.asm ******************************
|
||||
|
||||
110
WIN32LIB/SRCDEBUG/DS_RSRS.ASM
Normal file
110
WIN32LIB/SRCDEBUG/DS_RSRS.ASM
Normal file
@@ -0,0 +1,110 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_RSRS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : June 1, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Right_Scale_Reverse_Skip -- Skips past a scaled row of pixels *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Right_Scale_Reverse_Skip -- Skips past a scaled row of pixels *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape buffer data address *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* *
|
||||
;* WARNINGS: This routine may overrun the number of requested bytes *
|
||||
;* if it encounters a run of 0's; however, it's assumed that *
|
||||
;* the shape data will never contain a run that goes past the *
|
||||
;* right-hand edge of the shape. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/20/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/01/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Right_Scale_Reverse_Skip NOLANGUAGE NEAR
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jecxz ??out ; exit if ECX is 0 (no bytes to skip)
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz ??on_run ; if it is a run then deal with it
|
||||
jecxz ??out ; if we're done then get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Right_Scale_Reverse_Skip
|
||||
|
||||
END
|
||||
|
||||
;*************************** End of ds_rsrs.asm ****************************
|
||||
|
||||
110
WIN32LIB/SRCDEBUG/DS_RSS.ASM
Normal file
110
WIN32LIB/SRCDEBUG/DS_RSS.ASM
Normal file
@@ -0,0 +1,110 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_RSS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 24, 1993 *
|
||||
;* *
|
||||
;* Last Update : June 1, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Right_Scale_Skip -- Skips past a scaled row of pixels on right side *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************* Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;********************************* Code ************************************
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Right_Scale_Skip -- Skips past a scaled row of pixels on the right side *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* ECX = number of uncompressed bytes to skip *
|
||||
;* ESI = shape buffer data address *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* ESI - updated to the current location in the shape data *
|
||||
;* *
|
||||
;* WARNINGS: This routine may overrun the number of requested bytes *
|
||||
;* if it encounters a run of 0's; however, it's assumed that *
|
||||
;* the shape data will never contain a run that goes past the *
|
||||
;* right-hand edge of the shape. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/20/1992 PWG : Created. *
|
||||
;* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
;* 06/01/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
PROC Right_Scale_Skip NOLANGUAGE NEAR
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape data address in EDI so we can do a scasb on it
|
||||
;--------------------------------------------------------------------
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
jecxz ??out ; exit if ECX is 0 (no bytes to skip)
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Search through the string and count down the info we have handled.
|
||||
; If we find a run (0 followed by a count byte), then handle it.
|
||||
;--------------------------------------------------------------------
|
||||
??cliptop:
|
||||
mov eax,0 ; set al to 0 (we're scanning for 0)
|
||||
repne scasb ; scan through source data
|
||||
jz ??on_run ; if it is a run then deal with it
|
||||
jecxz ??out ; if we're done then get outta here
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; If we have a run then get the next byte which is the length.
|
||||
;--------------------------------------------------------------------
|
||||
??on_run:
|
||||
mov al,[BYTE PTR edi] ; get the count of zeros to run
|
||||
inc edi ; advance past the count
|
||||
inc ecx ; the 0 found doesn't count
|
||||
sub ecx,eax ; subtract the count from remaining
|
||||
jg ??cliptop ; if more bytes left, scan again
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Put shape address back into ESI, adjust EDI
|
||||
;--------------------------------------------------------------------
|
||||
??out:
|
||||
xchg esi,edi ; xchange ESI and EDI
|
||||
ret ; return back to the real function
|
||||
|
||||
ENDP Right_Scale_Skip
|
||||
|
||||
END
|
||||
|
||||
;*************************** End of ds_rss.asm *****************************
|
||||
|
||||
187
WIN32LIB/SRCDEBUG/DS_TABLE.ASM
Normal file
187
WIN32LIB/SRCDEBUG/DS_TABLE.ASM
Normal file
@@ -0,0 +1,187 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Draw Shape Routines for library. *
|
||||
;* *
|
||||
;* File Name : DS_TABLE.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : August 20, 1993 *
|
||||
;* *
|
||||
;* Last Update : September 6, 1994 [IML] *
|
||||
;* *
|
||||
;* This module sets up a table of procedure addresses for combinations of *
|
||||
;* NORMAL, HORZ_REV and SCALING flags. *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************** Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;******************************** Includes *********************************
|
||||
INCLUDE "shape.inc"
|
||||
|
||||
|
||||
;******************************** Equates **********************************
|
||||
;*=========================================================================*/
|
||||
;* The following are defines used to control what functions are linked *
|
||||
;* in for Draw_Shape. *
|
||||
;*=========================================================================*/
|
||||
USE_NORMAL EQU TRUE
|
||||
USE_HORZ_REV EQU TRUE
|
||||
USE_VERT_REV EQU TRUE
|
||||
USE_SCALING EQU TRUE
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
;
|
||||
; Use a macro to make code a little cleaner.
|
||||
; The parameter varname is optional.
|
||||
; Syntax to use macro is :
|
||||
; WANT equ expression
|
||||
; USE func [,varname]
|
||||
; If the 'varname' is defined, a table declaration is created like:
|
||||
; GLOBAL TableName:DWORD
|
||||
; Then, the table entry is created:
|
||||
; If WANT is true, the table entry is created for the given function:
|
||||
; varname DD func
|
||||
; If WANT is not TRUE, a Not_Supported entry is put in the table:
|
||||
; varname DD Not_Supported
|
||||
; The resulting tables look like:
|
||||
;
|
||||
; GLOBAL ExampTable:DWORD
|
||||
; ExampTable DD routine1
|
||||
; DD routine2
|
||||
; DD routine3
|
||||
; ...
|
||||
; Thus, each table is an array of function pointers.
|
||||
;
|
||||
;---------------------------------------------------------------------------
|
||||
MACRO USE func, varname
|
||||
IFNB <varname>
|
||||
GLOBAL varname:DWORD
|
||||
ENDIF
|
||||
IF WANT
|
||||
varname DD func
|
||||
ELSE
|
||||
varname DD Not_Supported
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Data Segment Tables:
|
||||
; This code uses the USE macro to set up tables of function addresses.
|
||||
; The tables have the following format:
|
||||
; Tables defined are:
|
||||
; LSkipTable
|
||||
; RSkipTable
|
||||
; DrawTable
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
DATASEG
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Left_Skip, LSkipTable
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Left_Reverse_Skip
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Left_Skip
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Left_Reverse_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Left_Scale_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Left_Scale_Reverse_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Left_Scale_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Left_Scale_Reverse_Skip
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Right_Skip, RSkipTable
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Right_Reverse_Skip
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Right_Skip
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Right_Reverse_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Right_Scale_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Right_Scale_Reverse_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Right_Scale_Skip
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Right_Scale_Reverse_Skip
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Draw_Normal, DrawTable
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Draw_Reverse
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Draw_Normal
|
||||
|
||||
WANT equ <TRUE>
|
||||
USE Draw_Reverse
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Draw_Scale
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Draw_Scale_Reverse
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Draw_Scale
|
||||
|
||||
WANT equ <USE_SCALING>
|
||||
USE Draw_Scale_Reverse
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
END
|
||||
|
||||
;************************** End of ds_table.asm ****************************
|
||||
91
WIN32LIB/SRCDEBUG/EXIT.CPP
Normal file
91
WIN32LIB/SRCDEBUG/EXIT.CPP
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : WWLIB32 library source *
|
||||
* *
|
||||
* File Name : EXIT.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : August 3, 1994 *
|
||||
* *
|
||||
* Last Update : August 3, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Exit -- Exit routine with message. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* EXIT -- Exit routine with message. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/03/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void __cdecl Exit(INT errorval, const char *message, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char errstring[256];
|
||||
|
||||
Prog_End();
|
||||
|
||||
if (message && *message) {
|
||||
va_start (argptr, message);
|
||||
vsprintf ((char *)errstring, (const char *)message, argptr);
|
||||
va_end (argptr);
|
||||
printf(errstring);
|
||||
}
|
||||
|
||||
::exit(errorval);
|
||||
|
||||
}
|
||||
|
||||
void randomize ( void )
|
||||
{
|
||||
srand ( time ( NULL ) ) ;
|
||||
}
|
||||
|
||||
#if(0)
|
||||
unsigned long random ( unsigned long mod )
|
||||
{
|
||||
return rand () * mod / RAND_MAX ;
|
||||
}
|
||||
#endif
|
||||
148
WIN32LIB/SRCDEBUG/FACING16.ASM
Normal file
148
WIN32LIB/SRCDEBUG/FACING16.ASM
Normal file
@@ -0,0 +1,148 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/source/rcs/./facing16.asm 1.10 1994/05/20 15:32:36 joe_bostic Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Support Library *
|
||||
;* *
|
||||
;* File Name : FACING16.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : May 8, 1991 *
|
||||
;* *
|
||||
;* Last Update : February 6, 1995 [BWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Desired_Facing16 -- Converts coordinates into a facing number. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Desired_Facing16 :NEAR
|
||||
; INCLUDE "wwlib.i"
|
||||
|
||||
DATASEG
|
||||
|
||||
; 16 direction desired facing lookup table. Build the index according
|
||||
; to the following bits:
|
||||
;
|
||||
; bit 4 = Is y2 < y1?
|
||||
; bit 3 = Is x2 < x1?
|
||||
; bit 2 = Is the ABS(x2-x1) < ABS(y2-y1)?
|
||||
; bit 1 = Is the lesser absolute difference very close to zero?
|
||||
; bit 0 = Is the lesser absolute difference very close to the greater dist?
|
||||
NewFacing16 DB 3, 2, 4,-1, 1, 2,0,-1
|
||||
DB 13,14,12,-1,15,14,0,-1
|
||||
DB 5, 6, 4,-1, 7, 6,8,-1
|
||||
DB 11,10,12,-1, 9,10,8,-1
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* DESIRED_FACING16 -- Converts coordinates into a facing number. *
|
||||
;* *
|
||||
;* This converts coordinates into a desired facing number that ranges *
|
||||
;* from 0 to 15 (0 equals North and going clockwise). *
|
||||
;* *
|
||||
;* INPUT: x1,y1 -- Position of origin point. *
|
||||
;* *
|
||||
;* x2,y2 -- Position of target. *
|
||||
;* *
|
||||
;* OUTPUT: Returns desired facing as a number from 0 to 255 but *
|
||||
;* accurate to 22.5 degree increments. *
|
||||
;* *
|
||||
;* WARNINGS: If the two coordinates are the same, then -1 will be *
|
||||
;* returned. It is up to you to handle this case. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 08/14/1991 JLB : Created. *
|
||||
;*=========================================================================*
|
||||
; long Desired_Facing16(long x1, long y1, long x2, long y2);
|
||||
|
||||
PROC Desired_Facing16 C near
|
||||
USES ebx, ecx, edx
|
||||
|
||||
ARG x1:DWORD
|
||||
ARG y1:DWORD
|
||||
ARG x2:DWORD
|
||||
ARG y2:DWORD
|
||||
|
||||
xor ebx,ebx ; Index byte (built).
|
||||
|
||||
; Determine Y axis difference.
|
||||
mov edx,[y1]
|
||||
mov ecx,[y2]
|
||||
sub edx,ecx ; DX = Y axis (signed).
|
||||
jns short ??absy
|
||||
inc ebx ; Set the signed bit.
|
||||
neg edx ; ABS(y)
|
||||
??absy:
|
||||
|
||||
; Determine X axis difference.
|
||||
shl ebx,1
|
||||
mov eax,[x1]
|
||||
mov ecx,[x2]
|
||||
sub ecx,eax ; CX = X axis (signed).
|
||||
jns short ??absx
|
||||
inc ebx ; Set the signed bit.
|
||||
neg ecx ; ABS(x)
|
||||
??absx:
|
||||
|
||||
; Determine the greater axis.
|
||||
cmp ecx,edx
|
||||
jb short ??dxisbig
|
||||
xchg ecx,edx
|
||||
??dxisbig:
|
||||
rcl ebx,1 ; Y > X flag bit.
|
||||
|
||||
; Determine the closeness or farness of lesser axis.
|
||||
mov eax,edx
|
||||
inc eax ; Round up.
|
||||
shr eax,1
|
||||
inc eax ; Round up.
|
||||
shr eax,1 ; 1/4 of greater axis.
|
||||
|
||||
cmp ecx,eax
|
||||
rcl ebx,1 ; Very close to major axis bit.
|
||||
|
||||
sub edx,eax
|
||||
cmp edx,ecx
|
||||
rcl ebx,1 ; Very far from major axis bit.
|
||||
|
||||
xor eax,eax
|
||||
mov al,[NewFacing16+ebx]
|
||||
|
||||
; Normalize to 0..FF range.
|
||||
shl eax,4
|
||||
|
||||
ret
|
||||
|
||||
ENDP Desired_Facing16
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
140
WIN32LIB/SRCDEBUG/FACING8.ASM
Normal file
140
WIN32LIB/SRCDEBUG/FACING8.ASM
Normal file
@@ -0,0 +1,140 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Support Library *
|
||||
;* *
|
||||
;* File Name : FACING8.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : May 8, 1991 *
|
||||
;* *
|
||||
;* Last Update : February 6, 1995 [BWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Desired_Facing8 -- Determines facing to reach a position. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
GLOBAL C Desired_Facing8 :NEAR
|
||||
; INCLUDE "wwlib.i"
|
||||
|
||||
DATASEG
|
||||
|
||||
; 8 direction desired facing lookup table. Build the index according
|
||||
; to the following bits:
|
||||
;
|
||||
; bit 3 = Is y2 < y1?
|
||||
; bit 2 = Is x2 < x1?
|
||||
; bit 1 = Is the ABS(x2-x1) < ABS(y2-y1)?
|
||||
; bit 0 = Is the facing closer to a major axis?
|
||||
NewFacing8 DB 1,2,1,0,7,6,7,0,3,2,3,4,5,6,5,4
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* DESIRED_FACING8 -- Determines facing to reach a position. *
|
||||
;* *
|
||||
;* This routine will return with the most desirable facing to reach *
|
||||
;* one position from another. It is accurate to a resolution of 0 to *
|
||||
;* 7. *
|
||||
;* *
|
||||
;* INPUT: x1,y1 -- Position of origin point. *
|
||||
;* *
|
||||
;* x2,y2 -- Position of target. *
|
||||
;* *
|
||||
;* OUTPUT: Returns desired facing as a number from 0..255 with an *
|
||||
;* accuracy of 32 degree increments. *
|
||||
;* *
|
||||
;* WARNINGS: If the two coordinates are the same, then -1 will be *
|
||||
;* returned. It is up to you to handle this case. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 07/15/1991 JLB : Documented. *
|
||||
;* 08/08/1991 JLB : Same position check. *
|
||||
;* 08/14/1991 JLB : New algorithm *
|
||||
;* 02/06/1995 BWG : Convert to 32-bit *
|
||||
;*=========================================================================*
|
||||
; long Desired_Facing8(long x1, long y1, long x2, long y2);
|
||||
|
||||
PROC Desired_Facing8 C near
|
||||
USES ebx, ecx, edx
|
||||
|
||||
ARG x1:DWORD
|
||||
ARG y1:DWORD
|
||||
ARG x2:DWORD
|
||||
ARG y2:DWORD
|
||||
|
||||
xor ebx,ebx ; Index byte (built).
|
||||
|
||||
; Determine Y axis difference.
|
||||
mov edx,[y1]
|
||||
mov ecx,[y2]
|
||||
sub edx,ecx ; DX = Y axis (signed).
|
||||
jns short ??absy
|
||||
inc ebx ; Set the signed bit.
|
||||
neg edx ; ABS(y)
|
||||
??absy:
|
||||
|
||||
; Determine X axis difference.
|
||||
shl ebx,1
|
||||
mov eax,[x1]
|
||||
mov ecx,[x2]
|
||||
sub ecx,eax ; CX = X axis (signed).
|
||||
jns short ??absx
|
||||
inc ebx ; Set the signed bit.
|
||||
neg ecx ; ABS(x)
|
||||
??absx:
|
||||
|
||||
; Determine the greater axis.
|
||||
cmp ecx,edx
|
||||
jb short ??dxisbig
|
||||
xchg ecx,edx
|
||||
??dxisbig:
|
||||
rcl ebx,1 ; Y > X flag bit.
|
||||
|
||||
; Determine the closeness or farness of lesser axis.
|
||||
mov eax,edx
|
||||
inc eax ; Round up.
|
||||
shr eax,1
|
||||
|
||||
cmp ecx,eax
|
||||
rcl ebx,1 ; Close to major axis bit.
|
||||
|
||||
xor eax,eax
|
||||
mov al,[NewFacing8+ebx]
|
||||
|
||||
; Normalize to 0..FF range.
|
||||
shl eax,5
|
||||
|
||||
ret
|
||||
|
||||
ENDP Desired_Facing8
|
||||
|
||||
|
||||
END
|
||||
165
WIN32LIB/SRCDEBUG/FACINGFF.ASM
Normal file
165
WIN32LIB/SRCDEBUG/FACINGFF.ASM
Normal file
@@ -0,0 +1,165 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Support Library *
|
||||
;* *
|
||||
;* File Name : FACINGFF.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : May 8, 1991 *
|
||||
;* *
|
||||
;* Last Update : February 6, 1995 [BWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Desired_Facing256 -- Determines facing to reach a position. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Desired_Facing256 :NEAR
|
||||
; INCLUDE "wwlib.i"
|
||||
INCLUDE "..\include\gbuffer.inc"
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Desired_Facing256 -- Desired facing algorithm 0..255 resolution. *
|
||||
;* *
|
||||
;* This is a desired facing algorithm that has a resolution of 0 *
|
||||
;* through 255. *
|
||||
;* *
|
||||
;* INPUT: srcx,srcy -- Source coordinate. *
|
||||
;* *
|
||||
;* dstx,dsty -- Destination coordinate. *
|
||||
;* *
|
||||
;* OUTPUT: Returns with the desired facing to face the destination *
|
||||
;* coordinate from the position of the source coordinate. North *
|
||||
;* is 0, East is 64, etc. *
|
||||
;* *
|
||||
;* WARNINGS: This routine is slower than the other forms of desired *
|
||||
;* facing calculation. Use this routine when accuracy is *
|
||||
;* required. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 12/24/1991 JLB : Adapted. *
|
||||
;*=========================================================================*/
|
||||
; LONG cdecl Desired_Facing256(LONG srcx, LONG srcy, LONG dstx, LONG dsty)
|
||||
PROC Desired_Facing256 C near
|
||||
USES ebx, ecx, edx
|
||||
|
||||
ARG srcx:DWORD
|
||||
ARG srcy:DWORD
|
||||
ARG dstx:DWORD
|
||||
ARG dsty:DWORD
|
||||
|
||||
xor ebx,ebx ; Facing number.
|
||||
|
||||
; Determine absolute X delta and left/right direction.
|
||||
mov ecx,[dstx]
|
||||
sub ecx,[srcx]
|
||||
jge short ??xnotneg
|
||||
neg ecx
|
||||
mov ebx,11000000b ; Set bit 7 and 6 for leftward.
|
||||
??xnotneg:
|
||||
|
||||
; Determine absolute Y delta and top/bottom direction.
|
||||
mov eax,[srcy]
|
||||
sub eax,[dsty]
|
||||
jge short ??ynotneg
|
||||
xor ebx,01000000b ; Complement bit 6 for downward.
|
||||
neg eax
|
||||
??ynotneg:
|
||||
|
||||
; Set DX=64 for quadrants 0 and 2.
|
||||
mov edx,ebx
|
||||
and edx,01000000b
|
||||
xor edx,01000000b
|
||||
|
||||
; Determine if the direction is closer to the Y axis and make sure that
|
||||
; CX holds the larger of the two deltas. This is in preparation for the
|
||||
; divide.
|
||||
cmp eax,ecx
|
||||
jb short ??gotaxis
|
||||
xchg eax,ecx
|
||||
xor edx,01000000b ; Closer to Y axis so make DX=64 for quad 0 and 2.
|
||||
??gotaxis:
|
||||
|
||||
; If closer to the X axis then add 64 for quadrants 0 and 2. If
|
||||
; closer to the Y axis then add 64 for quadrants 1 and 3. Determined
|
||||
; add value is in DX and save on stack.
|
||||
push edx
|
||||
|
||||
; Make sure that the division won't overflow. Reduce precision until
|
||||
; the larger number is less than 256 if it appears that an overflow
|
||||
; will occur. If the high byte of the divisor is not zero, then this
|
||||
; guarantees no overflow, so just abort shift operation.
|
||||
test eax,0FFFFFF00h
|
||||
jnz short ??nooverflow
|
||||
??again:
|
||||
test ecx,0FFFFFF00h
|
||||
jz short ??nooverflow
|
||||
shr ecx,1
|
||||
shr eax,1
|
||||
jmp short ??again
|
||||
??nooverflow:
|
||||
|
||||
; Make sure that the division won't underflow (divide by zero). If
|
||||
; this would occur, then set the quotient to $FF and skip divide.
|
||||
or ecx,ecx
|
||||
jnz short ??nounderflow
|
||||
mov eax,0FFFFFFFFh
|
||||
jmp short ??divcomplete
|
||||
|
||||
; Derive a pseudo angle number for the octant. The angle is based
|
||||
; on $00 = angle matches long axis, $00 = angle matches $FF degrees.
|
||||
??nounderflow:
|
||||
xor edx,edx
|
||||
shld edx,eax,8 ; shift high byte of eax into dl
|
||||
shl eax,8
|
||||
div ecx
|
||||
??divcomplete:
|
||||
|
||||
; Integrate the 5 most significant bits into the angle index. If DX
|
||||
; is not zero, then it is 64. This means that the dividend must be negated
|
||||
; before it is added into the final angle value.
|
||||
shr eax,3
|
||||
pop edx
|
||||
or edx,edx
|
||||
je short ??noneg
|
||||
dec edx
|
||||
neg eax
|
||||
??noneg:
|
||||
add eax,edx
|
||||
add eax,ebx
|
||||
and eax,0FFH
|
||||
ret
|
||||
|
||||
ENDP Desired_Facing256
|
||||
|
||||
|
||||
|
||||
END
|
||||
215
WIN32LIB/SRCDEBUG/FADING.ASM
Normal file
215
WIN32LIB/SRCDEBUG/FADING.ASM
Normal file
@@ -0,0 +1,215 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood Library *
|
||||
;* *
|
||||
;* File Name : FADING.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : August 20, 1993 *
|
||||
;* *
|
||||
;* Last Update : August 20, 1993 [JLB] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Build_Fading_Table :NEAR
|
||||
|
||||
CODESEG
|
||||
|
||||
;***********************************************************
|
||||
; BUILD_FADING_TABLE
|
||||
;
|
||||
; void *Build_Fading_Table(void *palette, void *dest, long int color, long int frac);
|
||||
;
|
||||
; This routine will create the fading effect table used to coerce colors
|
||||
; from toward a common value. This table is used when Fading_Effect is
|
||||
; active.
|
||||
;
|
||||
; Bounds Checking: None
|
||||
;*
|
||||
PROC Build_Fading_Table C near
|
||||
USES ebx, ecx, edi, esi
|
||||
ARG palette:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG color:DWORD
|
||||
ARG frac:DWORD
|
||||
|
||||
LOCAL matchvalue:DWORD ; Last recorded match value.
|
||||
LOCAL targetred:BYTE ; Target gun red.
|
||||
LOCAL targetgreen:BYTE ; Target gun green.
|
||||
LOCAL targetblue:BYTE ; Target gun blue.
|
||||
LOCAL idealred:BYTE
|
||||
LOCAL idealgreen:BYTE
|
||||
LOCAL idealblue:BYTE
|
||||
LOCAL matchcolor:BYTE ; Tentative match color.
|
||||
|
||||
cld
|
||||
|
||||
; If the source palette is NULL, then just return with current fading table pointer.
|
||||
cmp [palette],0
|
||||
je ??fini
|
||||
cmp [dest],0
|
||||
je ??fini
|
||||
|
||||
; Fractions above 255 become 255.
|
||||
mov eax,[frac]
|
||||
cmp eax,0100h
|
||||
jb short ??ok
|
||||
mov [frac],0FFh
|
||||
??ok:
|
||||
|
||||
; Record the target gun values.
|
||||
mov esi,[palette]
|
||||
mov ebx,[color]
|
||||
add esi,ebx
|
||||
add esi,ebx
|
||||
add esi,ebx
|
||||
lodsb
|
||||
mov [targetred],al
|
||||
lodsb
|
||||
mov [targetgreen],al
|
||||
lodsb
|
||||
mov [targetblue],al
|
||||
|
||||
; Main loop.
|
||||
xor ebx,ebx ; Remap table index.
|
||||
|
||||
; Transparent black never gets remapped.
|
||||
mov edi,[dest]
|
||||
mov [edi],bl
|
||||
inc edi
|
||||
|
||||
; EBX = source palette logical number (1..255).
|
||||
; EDI = running pointer into dest remap table.
|
||||
??mainloop:
|
||||
inc ebx
|
||||
mov esi,[palette]
|
||||
add esi,ebx
|
||||
add esi,ebx
|
||||
add esi,ebx
|
||||
|
||||
mov edx,[frac]
|
||||
shr edx,1
|
||||
; new = orig - ((orig-target) * fraction);
|
||||
|
||||
lodsb ; orig
|
||||
mov dh,al ; preserve it for later.
|
||||
sub al,[targetred] ; al = (orig-target)
|
||||
imul dl ; ax = (orig-target)*fraction
|
||||
shl ax,1
|
||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
||||
mov [idealred],dh ; preserve ideal color gun value.
|
||||
|
||||
lodsb ; orig
|
||||
mov dh,al ; preserve it for later.
|
||||
sub al,[targetgreen] ; al = (orig-target)
|
||||
imul dl ; ax = (orig-target)*fraction
|
||||
shl ax,1
|
||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
||||
mov [idealgreen],dh ; preserve ideal color gun value.
|
||||
|
||||
lodsb ; orig
|
||||
mov dh,al ; preserve it for later.
|
||||
sub al,[targetblue] ; al = (orig-target)
|
||||
imul dl ; ax = (orig-target)*fraction
|
||||
shl ax,1
|
||||
sub dh,ah ; dh = orig - ((orig-target) * fraction)
|
||||
mov [idealblue],dh ; preserve ideal color gun value.
|
||||
|
||||
; Sweep through the entire existing palette to find the closest
|
||||
; matching color. Never matches with color 0.
|
||||
|
||||
mov eax,[color]
|
||||
mov [matchcolor],al ; Default color (self).
|
||||
mov [matchvalue],-1 ; Ridiculous match value init.
|
||||
mov ecx,255
|
||||
|
||||
mov esi,[palette] ; Pointer to original palette.
|
||||
add esi,3
|
||||
|
||||
; BH = color index.
|
||||
mov bh,1
|
||||
??innerloop:
|
||||
|
||||
; Recursion through the fading table won't work if a color is allowed
|
||||
; to remap to itself. Prevent this from occuring.
|
||||
add esi,3
|
||||
cmp bh,bl
|
||||
je short ??notclose
|
||||
sub esi,3
|
||||
|
||||
xor edx,edx ; Comparison value starts null.
|
||||
mov eax,edx
|
||||
; Build the comparison value based on the sum of the differences of the color
|
||||
; guns squared.
|
||||
lodsb
|
||||
sub al,[idealred]
|
||||
mov ah,al
|
||||
imul ah
|
||||
add edx,eax
|
||||
|
||||
lodsb
|
||||
sub al,[idealgreen]
|
||||
mov ah,al
|
||||
imul ah
|
||||
add edx,eax
|
||||
|
||||
lodsb
|
||||
sub al,[idealblue]
|
||||
mov ah,al
|
||||
imul ah
|
||||
add edx,eax
|
||||
jz short ??perfect ; If perfect match found then quit early.
|
||||
|
||||
cmp edx,[matchvalue]
|
||||
ja short ??notclose
|
||||
mov [matchvalue],edx ; Record new possible color.
|
||||
mov [matchcolor],bh
|
||||
??notclose:
|
||||
inc bh ; Checking color index.
|
||||
loop ??innerloop
|
||||
mov bh,[matchcolor]
|
||||
??perfect:
|
||||
mov [matchcolor],bh
|
||||
xor bh,bh ; Make BX valid main index again.
|
||||
|
||||
; When the loop exits, we have found the closest match.
|
||||
mov al,[matchcolor]
|
||||
stosb
|
||||
cmp ebx,255
|
||||
jne ??mainloop
|
||||
|
||||
??fini:
|
||||
mov eax,[dest]
|
||||
ret
|
||||
|
||||
ENDP Build_Fading_Table
|
||||
|
||||
|
||||
END
|
||||
238
WIN32LIB/SRCDEBUG/FFIRST.ASM
Normal file
238
WIN32LIB/SRCDEBUG/FFIRST.ASM
Normal file
@@ -0,0 +1,238 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : First First *
|
||||
;* *
|
||||
;* File Name : FFIRST.ASM *
|
||||
;* *
|
||||
;* Programmer : Jeff Wilson *
|
||||
;* *
|
||||
;* Start Date : March 28, 1994 *
|
||||
;* *
|
||||
;* Last Update : April 15, 1994 [] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Find_First -- Find a file spec *
|
||||
;* Find_Next -- Find next file in sreach params *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
LOCALS ??
|
||||
|
||||
GLOBAL Find_First :NEAR
|
||||
GLOBAL Find_Next :NEAR
|
||||
|
||||
;============================================================================
|
||||
CODESEG
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* FIND_FIRST -- Find a file spec *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* file_name File spec to find. Maybe a wildcard name *
|
||||
;* mode File type *
|
||||
;* ffblk file data block ptr to write info into *
|
||||
;* *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/15/1994 jaw: Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC Find_First C near
|
||||
USES ebx,ecx,edx,esi,edi,es,ds
|
||||
ARG file_name:DWORD,mode:WORD,ffblk:DWORD
|
||||
|
||||
mov edx,[file_name]
|
||||
mov cx,[mode]
|
||||
|
||||
mov eax,4e00h ;first firstg function
|
||||
|
||||
int 21h
|
||||
;Find it?
|
||||
jnc ??found_it ;=>yes
|
||||
|
||||
; ax holds the error code
|
||||
;insure high word of eax is clear
|
||||
or eax,0ffffffffh
|
||||
jmp ??exit
|
||||
|
||||
??found_it:
|
||||
; found something
|
||||
;copy the DTA into the user block
|
||||
mov eax,2f00h ;get DTA address
|
||||
int 21h
|
||||
|
||||
mov ax,es ;switch selectors
|
||||
mov dx,ds
|
||||
mov ds,ax
|
||||
mov es,dx
|
||||
|
||||
mov esi,ebx
|
||||
mov edi,[ffblk]
|
||||
|
||||
add esi,21 ;SKIP RESERVED
|
||||
add edi,4 ;SKIP RESERVED
|
||||
|
||||
sub eax,eax
|
||||
mov al,[esi] ;get attrib byte
|
||||
mov [es:edi+4],eax
|
||||
inc esi
|
||||
|
||||
;get time
|
||||
mov ax,[esi]
|
||||
add esi,2
|
||||
mov [es:edi+8],ax
|
||||
|
||||
;get date
|
||||
mov ax,[esi]
|
||||
add esi,2
|
||||
mov [es:edi+10],ax
|
||||
|
||||
;get file size
|
||||
mov eax,[esi]
|
||||
add esi,4
|
||||
mov [es:edi],eax
|
||||
|
||||
add edi,12
|
||||
|
||||
mov ecx,13
|
||||
|
||||
rep movsb ;copy the DTA name
|
||||
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
;====================
|
||||
ENDP Find_First
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* FIND_NEXT -- Find next file in sreach params *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* NONE *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/15/1994 jaw: Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC Find_Next C near
|
||||
USES ebx,ecx,edx,esi,edi,ds,es
|
||||
|
||||
ARG ffblk:DWORD
|
||||
|
||||
mov eax,04f00h ;Find Next function
|
||||
|
||||
int 21h
|
||||
;Find anything?
|
||||
jnc ??found_it ;=>no
|
||||
|
||||
; ax holds the error code
|
||||
;insure high word of eax is clear
|
||||
or eax,0ffffffffh
|
||||
jmp ??exit
|
||||
|
||||
??found_it:
|
||||
; found something
|
||||
;copy the DTA into the user block
|
||||
mov eax,2f00h ;get DTA address
|
||||
int 21h
|
||||
|
||||
mov ax,es ;switch selectors
|
||||
mov dx,ds
|
||||
mov ds,ax
|
||||
mov es,dx
|
||||
|
||||
mov esi,ebx
|
||||
mov edi,[ffblk]
|
||||
|
||||
add esi,21 ;SKIP RESERVED
|
||||
add edi,4 ;SKIP RESERVED
|
||||
|
||||
sub eax,eax
|
||||
mov al,[esi] ;get attrib byte
|
||||
mov [es:edi+4],eax
|
||||
inc esi
|
||||
|
||||
;get time
|
||||
mov ax,[esi]
|
||||
add esi,2
|
||||
mov [es:edi+8],ax
|
||||
|
||||
;get date
|
||||
mov ax,[esi]
|
||||
add esi,2
|
||||
mov [es:edi+10],ax
|
||||
|
||||
;get file size
|
||||
mov eax,[esi]
|
||||
add esi,4
|
||||
mov [es:edi],eax
|
||||
|
||||
add edi,12
|
||||
|
||||
mov ecx,13
|
||||
|
||||
rep movsb ;copy the DTA name
|
||||
|
||||
mov ax,es
|
||||
mov ds,ax
|
||||
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Find_Next
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
94
WIN32LIB/SRCDEBUG/FFIXSEL.ASM
Normal file
94
WIN32LIB/SRCDEBUG/FFIXSEL.ASM
Normal file
@@ -0,0 +1,94 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Fix a selector *
|
||||
;* *
|
||||
;* File Name : FFIXSEL.ASM *
|
||||
;* *
|
||||
;* Programmer : Jeff Wilson *
|
||||
;* *
|
||||
;* Start Date : March 28, 1994 *
|
||||
;* *
|
||||
;* Last Update : March 28, 1994 [] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* FixSelector -- Fix the Priviledge level of a selector *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
EXTRN exit : near
|
||||
GLOBAL FixSelector :NEAR
|
||||
|
||||
;============================================================================
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* FIXSELECTOR -- Fix the Priviledge level of a selector *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: sel the selector to fix-up *
|
||||
;* *
|
||||
;* OUTPUT: UWORD The fixed up selector *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/28/1994 jaw Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC FixSelector C near
|
||||
|
||||
USES ecx,edx
|
||||
|
||||
ARG sel:WORD
|
||||
|
||||
; Copy the Table Bit and IOPL from the Current CS
|
||||
|
||||
; Something is wrong the program should not be here unthe any circunstance
|
||||
; movzx ecx,[sel]
|
||||
; xor eax,eax
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,cx
|
||||
push 0
|
||||
call exit
|
||||
|
||||
ret
|
||||
;====================
|
||||
ENDP FixSelector
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
78
WIN32LIB/SRCDEBUG/FGETCS.ASM
Normal file
78
WIN32LIB/SRCDEBUG/FGETCS.ASM
Normal file
@@ -0,0 +1,78 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Get the code selector *
|
||||
;* *
|
||||
;* File Name : FGETCS.ASM *
|
||||
;* *
|
||||
;* Programmer : Jeff Wilson *
|
||||
;* *
|
||||
;* Start Date : March 28, 1994 *
|
||||
;* *
|
||||
;* Last Update : March 28, 1994 [] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* GetCs -- Return the current Data selector. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
GLOBAL GetCs :NEAR
|
||||
|
||||
;============================================================================
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* GETCS -- Return the current Data selector. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: NONE *
|
||||
;* *
|
||||
;* OUTPUT: UWORD selector of the default code segment *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/28/1994 jaw: Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC GetCs C near
|
||||
|
||||
xor eax,eax
|
||||
mov ax,cs
|
||||
ret
|
||||
;====================
|
||||
ENDP GetCs
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
77
WIN32LIB/SRCDEBUG/FGETDS.ASM
Normal file
77
WIN32LIB/SRCDEBUG/FGETDS.ASM
Normal file
@@ -0,0 +1,77 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Get the data selector *
|
||||
;* *
|
||||
;* File Name : FGETDS.ASM *
|
||||
;* *
|
||||
;* Programmer : Jeff Wilson *
|
||||
;* *
|
||||
;* Start Date : March 28, 1994 *
|
||||
;* *
|
||||
;* Last Update : March 28, 1994 [] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* GetDs -- Return the current Data selector. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
GLOBAL GetDs :NEAR
|
||||
|
||||
;============================================================================
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* GETDS -- Return the current Data selector. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: NONE *
|
||||
;* *
|
||||
;* OUTPUT: UWORD selector of the default data segment *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/28/1994 jaw: Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC GetDs C near
|
||||
|
||||
xor eax,eax
|
||||
mov ax,ds
|
||||
ret
|
||||
;====================
|
||||
ENDP GetDs
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
118
WIN32LIB/SRCDEBUG/FGETSEL.ASM
Normal file
118
WIN32LIB/SRCDEBUG/FGETSEL.ASM
Normal file
@@ -0,0 +1,118 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Get the Defines selectors *
|
||||
;* *
|
||||
;* File Name : FGETSEL.ASM *
|
||||
;* *
|
||||
;* Programmer : Jeff Wilson *
|
||||
;* *
|
||||
;* Start Date : March 28, 1994 *
|
||||
;* *
|
||||
;* Last Update : March 28, 1994 [] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* GetDefaultSelectors -- Return the current default selectors. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
GLOBAL GetDefaultSelectors :NEAR
|
||||
|
||||
GLOBAL DataSelector :WORD
|
||||
GLOBAL ScreenSelector :WORD
|
||||
GLOBAL GraphicsSelector :WORD
|
||||
GLOBAL PspSelector :WORD
|
||||
GLOBAL EnvSelector :WORD
|
||||
GLOBAL DosMemSelector :WORD
|
||||
GLOBAL Fp1167Selector :WORD
|
||||
GLOBAL FpWeitekSelector :WORD
|
||||
GLOBAL FpCyrixSelector :WORD
|
||||
GLOBAL CodeSelector :WORD
|
||||
|
||||
|
||||
DATASEG
|
||||
|
||||
; It is very important that this section remain untouch
|
||||
; is not really needed by Rational System but is here to
|
||||
; keep compatibility with the TNT dos extender.
|
||||
DataSelector dw 0
|
||||
ScreenSelector dw 0
|
||||
GraphicsSelector dw 0
|
||||
|
||||
PspSelector dw 0
|
||||
EnvSelector dw 0
|
||||
DosMemSelector dw 0
|
||||
|
||||
Fp1167Selector dw 0
|
||||
FpWeitekSelector dw 0
|
||||
FpCyrixSelector dw 0
|
||||
|
||||
CodeSelector dw 0
|
||||
|
||||
|
||||
;============================================================================
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* GetDefaultSelectors -- Setup the defaults selector values to have the *
|
||||
;* Correct Descriptor table and IOPL. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: NONE *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/28/1994 jaw: Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC GetDefaultSelectors C near
|
||||
USES eax,esi,ecx
|
||||
|
||||
lea edi,[DataSelector]
|
||||
lea ecx,[CodeSelector]
|
||||
sub ecx,edi
|
||||
shr ecx,1
|
||||
mov ax,ds
|
||||
rep stosw
|
||||
mov ax,cs
|
||||
mov [word ptr CodeSelector] , ax
|
||||
|
||||
ret
|
||||
;====================
|
||||
ENDP GetDefaultSelectors
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
41
WIN32LIB/SRCDEBUG/FGLOB2.CPP
Normal file
41
WIN32LIB/SRCDEBUG/FGLOB2.CPP
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : FILEIO Library *
|
||||
* *
|
||||
* File Name : FILEGLOB.C *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : April 11, 1994 *
|
||||
* *
|
||||
* Last Update : April 11, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <wwstd.h>
|
||||
#include "_file.h"
|
||||
|
||||
/* Global varaiables */
|
||||
WORD Hard_Error_Occured=0;
|
||||
1070
WIN32LIB/SRCDEBUG/FILE.CPP
Normal file
1070
WIN32LIB/SRCDEBUG/FILE.CPP
Normal file
File diff suppressed because it is too large
Load Diff
250
WIN32LIB/SRCDEBUG/FILECACH.CPP
Normal file
250
WIN32LIB/SRCDEBUG/FILECACH.CPP
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Library - File Caching routines *
|
||||
* *
|
||||
* File Name : FILECACH.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : September 13, 1993 *
|
||||
* *
|
||||
* Last Update : April 18, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Make_File_Resident -- Makes a file resident even if not flaged so. *
|
||||
* Flush_Unused_File_Cache -- Flushes the file cache of any non opened fi*
|
||||
* Free_Resident_File -- Free the given file if it is resident. *
|
||||
* Unfragment_File_Cache -- Does a garbage collection on the file heap. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#ifndef WWSTD_H
|
||||
#include <wwstd.h>
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#ifndef WWMEM_H
|
||||
#include <wwmem.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* UNFRAGMENT_FILE_CACHE -- Does a garbage collection on the file heap. *
|
||||
* *
|
||||
* INPUT: NONE. *
|
||||
* *
|
||||
* OUTPUT: NONE. *
|
||||
* *
|
||||
* WARNINGS: Can be a lengthy process. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/18/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
VOID Unfragment_File_Cache(VOID)
|
||||
{
|
||||
FileDataType *filedata;
|
||||
FileDataType *parent;
|
||||
UWORD idx;
|
||||
|
||||
|
||||
// Let the memory system clean up the file heap.
|
||||
Mem_Cleanup(FileCacheHeap);
|
||||
|
||||
// Now get our pointers back.
|
||||
// Start after the parent PAK files since we will need to check our pointers
|
||||
// with them.
|
||||
filedata = &FileDataPtr[NumPAKFiles];
|
||||
for (idx = NumPAKFiles; idx < NumPAKFiles; idx++, filedata++) {
|
||||
while (filedata->Name) {
|
||||
|
||||
// Only process files that are in the file cache.
|
||||
if (filedata->Ptr) {
|
||||
|
||||
// Is a inner PAK file?
|
||||
if (filedata->Flag & FILEF_PACKED) {
|
||||
|
||||
parent = &FileDataPtr[filedata->Disk];
|
||||
|
||||
// Is it just a copied pointer of the parent?
|
||||
if (parent->Ptr == filedata->Ptr) {
|
||||
filedata->Ptr = Mem_Find(FileCacheHeap, filedata->Disk);
|
||||
}
|
||||
else
|
||||
filedata->Ptr = Mem_Find(FileCacheHeap, idx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
filedata->Ptr = Mem_Find(FileCacheHeap, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that the children have been taken care of, let us do the parents.
|
||||
for (filedata = FileDataPtr, idx = 0; idx < NumPAKFiles; idx++, filedata++) {
|
||||
|
||||
// Only process files that are in the file cache.
|
||||
if (filedata->Ptr) {
|
||||
filedata->Ptr = Mem_Find(FileCacheHeap, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* MAKE_FILE_RESIDENT -- Makes a file resident even if not flaged so. *
|
||||
* *
|
||||
* INPUT: BYTE *filename - name of file to be made resident. *
|
||||
* *
|
||||
* OUTPUT: BOOL if successful. could fail in not enouph RAM or not found. *
|
||||
* *
|
||||
* WARNINGS: File must be in FileData table. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/13/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
BOOL Make_File_Resident(BYTE const *filename)
|
||||
{
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
|
||||
WORD fileindex;
|
||||
WORD oldflag;
|
||||
WORD handle;
|
||||
|
||||
fileindex = Find_File_Index(filename);
|
||||
|
||||
// if the file is not in the table, we can't make it resident
|
||||
if (fileindex == ERROR) return(FALSE);
|
||||
|
||||
// Get a pointer for quicker pointer action.
|
||||
filedata = &FileDataPtr[fileindex];
|
||||
|
||||
// Change the flags for a moment.
|
||||
oldflag = filedata->Flag;
|
||||
filedata->Flag |= FILEF_RESIDENT;
|
||||
filedata->Flag &= ~FILEF_FLUSH;
|
||||
|
||||
// Make the file resident.
|
||||
handle = Open_File(filename, READ);
|
||||
Close_File(handle);
|
||||
|
||||
// Set flags back to normal.
|
||||
filedata->Flag = oldflag;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Flush_Unused_File_Cache -- Flushes the file cache of any non opened files. *
|
||||
* *
|
||||
* INPUT: WORD flush_keep - TRUE to flush even files marked FILEF_KEEP.*
|
||||
* *
|
||||
* OUTPUT: WORD Number of file flushed. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/23/1993 SB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD Flush_Unused_File_Cache(WORD flush_keeps)
|
||||
{
|
||||
WORD index;
|
||||
WORD freed = 0;
|
||||
FileDataType *filedata = NULL;
|
||||
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
|
||||
|
||||
// Loop throuph the file table looking for files that could be freed.
|
||||
index = 0;
|
||||
filedata = &FileDataPtr[index];;
|
||||
while (filedata->Name && strlen(filedata->Name)) {
|
||||
|
||||
if (filedata->Ptr && !filedata->OpenCount &&
|
||||
(flush_keeps || !(filedata->Flag & FILEF_KEEP)) ) {
|
||||
|
||||
Mem_Free(FileCacheHeap, filedata->Ptr);
|
||||
filedata->Ptr = NULL;
|
||||
freed++;
|
||||
}
|
||||
index++;
|
||||
filedata = &FileDataPtr[index];;
|
||||
}
|
||||
return (freed);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* FREE_RESIDENT_FILE -- Free the given file if it is resident. *
|
||||
* *
|
||||
* INPUT: BYTE *file to free *
|
||||
* *
|
||||
* OUTPUT: TRUE if file was free'd, FALSE otherwise *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/22/1992 CY : Created. *
|
||||
*=========================================================================*/
|
||||
BOOL cdecl Free_Resident_File(BYTE const *file)
|
||||
{
|
||||
WORD fileindex;
|
||||
BOOL oldflag; // Previous file flag.
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
|
||||
|
||||
|
||||
// if the file is not in the table, we can't free it
|
||||
if ((fileindex = Find_File_Index(file)) == ERROR) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// get a pointer for quicker calculations.
|
||||
filedata = &FileDataPtr[fileindex];
|
||||
|
||||
// If it isn't resident, don't try to Free it
|
||||
if (filedata->Ptr == NULL) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
// Change the flags for a moment.
|
||||
oldflag = filedata->Flag;
|
||||
filedata->Flag &= ~(FILEF_RESIDENT|FILEF_KEEP);
|
||||
filedata->Flag |= FILEF_FLUSH;
|
||||
|
||||
// Get the file out of Memory if it was there.
|
||||
Close_File(Open_File(file, READ));
|
||||
|
||||
// Set flags back to original.
|
||||
filedata->Flag = oldflag;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
154
WIN32LIB/SRCDEBUG/FILECHNG.CPP
Normal file
154
WIN32LIB/SRCDEBUG/FILECHNG.CPP
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Library - File functions. *
|
||||
* *
|
||||
* File Name : FILECHNG.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : September 13, 1993 *
|
||||
* *
|
||||
* Last Update : September 13, 1993 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Delete_File -- Deletes the file from the disk. *
|
||||
* Create_File -- Creates an empty file on disk. *
|
||||
* Change_File_Size -- Change the size of a writting file. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#ifndef WWMEM_H
|
||||
#include <wwmem.h>
|
||||
#endif
|
||||
|
||||
#include <io.h>
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
/***************************************************************************
|
||||
* CREATE_FILE -- Creates an empty file on disk. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/24/1992 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Create_File(BYTE const *file_name)
|
||||
{
|
||||
WORD fd;
|
||||
|
||||
if (!file_name) return(FALSE);
|
||||
|
||||
fd = Open_File(file_name, WRITE);
|
||||
if (fd != ERROR) {
|
||||
Close_File(fd);
|
||||
return(TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* DELETE_FILE -- Deletes the file from the disk. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/24/1992 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Delete_File(BYTE const *file_name)
|
||||
{
|
||||
WORD index;
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
FileDataType hold; // Hold buffer for record (DO NOT ACCESS DIRECTLY)
|
||||
|
||||
if (!file_name) return(FALSE);
|
||||
|
||||
CallingDOSInt++;
|
||||
|
||||
ibm_setdisk(*StartPath - 'A');
|
||||
|
||||
index = Find_File_Index(file_name);
|
||||
filedata = &FileDataPtr[index];
|
||||
|
||||
if (index != ERROR && filedata->Ptr) {
|
||||
Mem_Free(FileCacheHeap, filedata->Ptr);
|
||||
filedata->Ptr = NULL;
|
||||
}
|
||||
|
||||
index = !FILEDELETE(file_name);
|
||||
CallingDOSInt--;
|
||||
return(index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CHANGE_FILE_SIZE -- Change the size of a writting file. *
|
||||
* *
|
||||
* INPUT: WORD handle - handle of file. *
|
||||
* ULONG new_size - size of new handle. *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/13/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
BOOL cdecl Change_File_Size(WORD handle, ULONG new_size)
|
||||
{
|
||||
WORD entry;
|
||||
|
||||
if (Is_Handle_Valid(handle, WRITING_NON_HANDLE, NULL)) {
|
||||
entry = Get_DOS_Handle(handle);
|
||||
if (entry != ERROR) {
|
||||
return(chsize(entry, new_size) != ERROR);
|
||||
}
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
72
WIN32LIB/SRCDEBUG/FILEDATA.CPP
Normal file
72
WIN32LIB/SRCDEBUG/FILEDATA.CPP
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : File IO System LIbrary *
|
||||
* *
|
||||
* File Name : FILEDATA.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : April 11, 1994 *
|
||||
* *
|
||||
* Last Update : April 11, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
/*
|
||||
structure for FileDataType is:
|
||||
|
||||
BYTE *filename: initialize to actual file name on disk.
|
||||
LONG size: initialize to actual file size on disk.
|
||||
BYTE *ptr: initialize to a 0L below.
|
||||
WORD disk: which floppy disk number (1+) file resides on.
|
||||
LONG pos: initialize to a 0L below.
|
||||
UBYTE priority: file priorities can be from 0 to 127. (127 = highest)
|
||||
if you want the file to be attempted to be made
|
||||
resident at runtime, add 128 to the file priority
|
||||
to set the high bit. even though the files
|
||||
priority will appear to be 128 to 255, it will
|
||||
still remain 0 to 127.
|
||||
*/
|
||||
|
||||
FileDataType FileData[] = {
|
||||
{ "", 0L, 0L, 0, 0L, 0 }
|
||||
/* Must have an empty entry!!! */
|
||||
};
|
||||
74
WIN32LIB/SRCDEBUG/FILEGLOB.CPP
Normal file
74
WIN32LIB/SRCDEBUG/FILEGLOB.CPP
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : FILEIO Library *
|
||||
* *
|
||||
* File Name : FILEGLOB.C *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : April 11, 1994 *
|
||||
* *
|
||||
* Last Update : April 11, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef WWSTD_H
|
||||
#include <wwstd.h>
|
||||
#endif
|
||||
|
||||
#ifndef FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#include <process.h>
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
/* Global varaiables */
|
||||
BYTE ExecPath[XMAXPATH + 1];
|
||||
BYTE DataPath[XMAXPATH + 1];
|
||||
BYTE StartPath[XMAXPATH + 1];
|
||||
BOOL UseCD;
|
||||
|
||||
/* File System only Global varaiables */
|
||||
BYTE CallingDOSInt; // Indicate we are performing a DOS function
|
||||
BYTE MaxDevice,DefaultDrive;
|
||||
BYTE MultiDriveSearch = TRUE; // Multiple drive search flag
|
||||
FileDataType *FileDataPtr = NULL;
|
||||
FileHandleType FileHandleTable[TABLE_MAX];
|
||||
UWORD NumFiles; // Number of files, except PAK, in file table.
|
||||
UWORD NumPAKFiles; // Number of PAK files in filetable.
|
||||
VOID *FileCacheHeap = NULL; // Pointer to the cache in memory.
|
||||
WORD DiskNumber; // Where file was found (-1 == current directory).
|
||||
WORD MaxDirNum = 0;
|
||||
|
||||
|
||||
WORD (*Open_Error)(FileErrorType, BYTE const *) = NULL;
|
||||
276
WIN32LIB/SRCDEBUG/FILEINFO.CPP
Normal file
276
WIN32LIB/SRCDEBUG/FILEINFO.CPP
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Library - Fileio information functions. *
|
||||
* *
|
||||
* File Name : FILE.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : September 13, 1993 *
|
||||
* *
|
||||
* Last Update : April 19, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Get_DOS_Handle -- Fetches system specific DOS file handle. *
|
||||
* Find_Disk_Number -- Determine disk a file resides upon. *
|
||||
* Set_File_Flags -- Sets flags for file if FileData table. *
|
||||
* Get_File_Flags -- Gets the flags on a file in the FileData table. *
|
||||
* Free_Handles -- Returns number of free file handles in WW system. *
|
||||
* Multi_Drive_Search -- Turns Multi search drive on and off. *
|
||||
* Clear_File_Flags -- Clears flags specified for file. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GET_DOS_HANDLE -- Fetches system specific DOS file handle. *
|
||||
* *
|
||||
* This routine will return with the system specific DOS file handle. *
|
||||
* On the IBM, this is a WORD, on the Amiga, it is a LONG (BPTR). Use *
|
||||
* this routine with caution, because the value returned is NOT *
|
||||
* portable. *
|
||||
* *
|
||||
* INPUT: fh -- Westwood file system handle. *
|
||||
* *
|
||||
* OUTPUT: Returns with the system DOS file handle (WORD or LONG). *
|
||||
* *
|
||||
* WARNINGS: If you pass in an invalid file handle, or a file handle *
|
||||
* that references a resident file, then the ERROR code is *
|
||||
* returned. Be SURE to check for this. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/21/1991 JLB : Created. *
|
||||
* 11/09/1991 JLB : Checks for illegal file handle passed in. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Get_DOS_Handle(WORD fh)
|
||||
{
|
||||
/*
|
||||
** If an illegal file handle is passed in then always abort.
|
||||
*/
|
||||
if (fh >= 0 && fh < TABLE_MAX) {
|
||||
if (!FileHandleTable[fh].Empty || FileHandleTable[fh].Handle) {
|
||||
return(FileHandleTable[fh].Handle);
|
||||
}
|
||||
|
||||
/*
|
||||
** If it falls through here, then the file must be resident. It is
|
||||
** illegal to get a DOS handle to a resident file.
|
||||
*/
|
||||
}
|
||||
return(FILEOPENERROR);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* FREE_HANDLES -- Returns number of free file handles in WW system. *
|
||||
* *
|
||||
* INPUT: NONE. *
|
||||
* *
|
||||
* OUTPUT: NONE. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/13/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Free_Handles(VOID)
|
||||
{
|
||||
WORD count; // Count of the number of free file handles.
|
||||
WORD index; // Working file handle index var.
|
||||
|
||||
count = 0;
|
||||
for (index = 0; index < TABLE_MAX; index++) {
|
||||
if (FileHandleTable[index].Empty) count++;
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FIND_DISK_NUMBER -- Determine disk a file resides upon. *
|
||||
* *
|
||||
* This routine will determine the disk number that the specified *
|
||||
* file resides upon. It determines this by scanning through the *
|
||||
* FileData table. If the specified file is a packed file, then it *
|
||||
* will reference the parent packed file to determine the disk number. *
|
||||
* *
|
||||
* INPUT: file_name -- Pointer to the file name to check. *
|
||||
* *
|
||||
* OUTPUT: Returns with the disk number that the file resides upon. If *
|
||||
* ERROR is returned, then the file does not exist in the *
|
||||
* FileTable. The number returned is 0=A, 1=B, etc. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/22/1991 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Find_Disk_Number(BYTE const *file_name)
|
||||
{
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
WORD index; // FileTable index.
|
||||
|
||||
index = Find_File_Index(file_name);
|
||||
|
||||
if (index != ERROR) {
|
||||
|
||||
filedata = &FileDataPtr[index];
|
||||
|
||||
if (filedata->Flag & FILEF_PACKED) {
|
||||
return (Find_Disk_Number(FileDataPtr[filedata->Disk].Name));
|
||||
}
|
||||
return(filedata->Disk);
|
||||
}
|
||||
return (index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* SET_FILE_FLAGS -- Sets flags for file if FileData table. *
|
||||
* *
|
||||
* INPUT: BYTE *filename - file to modify. *
|
||||
* WORD flags - flags to set in file. *
|
||||
* *
|
||||
* OUTPUT: WORD - if file found in FileData table. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/04/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Set_File_Flags(BYTE const *filename, WORD flags)
|
||||
{
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
WORD index; // FileTable index.
|
||||
|
||||
index = Find_File_Index(filename);
|
||||
|
||||
if (index != ERROR) {
|
||||
filedata = &FileDataPtr[index];
|
||||
filedata->Flag |= flags;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CLEAR_FILE_FLAGS -- Clears flags specified for file. *
|
||||
* *
|
||||
* INPUT: BYTE *filename - file to modify. *
|
||||
* WORD flags - flags to set in file. *
|
||||
* *
|
||||
* OUTPUT: WORD - if file found in FileData table. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Clear_File_Flags(BYTE const *filename, WORD flags)
|
||||
{
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
WORD index; // FileTable index.
|
||||
|
||||
index = Find_File_Index(filename);
|
||||
|
||||
if (index != ERROR) {
|
||||
filedata = &FileDataPtr[index];
|
||||
filedata->Flag &= ~flags;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GET_FILE_FLAGS -- Gets the flags on a file in the FileData table. *
|
||||
* *
|
||||
* *
|
||||
* INPUT: BYTE *filename - file to modify. *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* OUTPUT: WORD - if file found in FileData table. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/04/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Get_File_Flags(BYTE const *filename)
|
||||
{
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
WORD index; // FileTable index.
|
||||
|
||||
index = Find_File_Index(filename);
|
||||
|
||||
if (index != ERROR) {
|
||||
filedata = &FileDataPtr[index];
|
||||
return (filedata->Flag);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* MULTI_DRIVE_SEARCH -- Turns Multi search drive on and off. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/13/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
BOOL cdecl Multi_Drive_Search(BOOL on)
|
||||
{
|
||||
BOOL old;
|
||||
|
||||
Hard_Error_Occured = 0;
|
||||
old = MultiDriveSearch;
|
||||
MultiDriveSearch = on;
|
||||
return(old);
|
||||
}
|
||||
511
WIN32LIB/SRCDEBUG/FILEINIT.CPP
Normal file
511
WIN32LIB/SRCDEBUG/FILEINIT.CPP
Normal file
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Library - Fileio init routines. *
|
||||
* *
|
||||
* File Name : FILEINIT.C *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : September 13, 1993 *
|
||||
* *
|
||||
* Last Update : April 19, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* WWDOS_Init -- Initialize the fileio WWS fileio system. *
|
||||
* WWDOS_Shutdown -- Clean up any things that needs to be to exit game. *
|
||||
* Init_FileData_Table -- Initializes or reads in FileData Table. *
|
||||
* Sort_FileData_Table -- Sorts the FileData table that is in memory. *
|
||||
* Preload_Files -- Loads files marked with FILEF_PRELOAD into cache. *
|
||||
* Init_File_Cache -- Initializes and allocs the file cache heap. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#ifndef WWMEM_H
|
||||
#include <wwmem.h>
|
||||
#endif
|
||||
|
||||
#ifndef MISC_H
|
||||
#include <misc.h>
|
||||
#endif
|
||||
|
||||
#include <direct.h>
|
||||
#include <search.h>
|
||||
#include <string.h>
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
PRIVATE FileInitErrorType cdecl Init_File_Cache(ULONG cachesize);
|
||||
PRIVATE FileInitErrorType cdecl Init_FileData_Table(BYTE const *filename);
|
||||
PRIVATE FileInitErrorType cdecl Set_Search_Drives( BYTE *cdpath );
|
||||
PRIVATE FileInitErrorType cdecl Preload_Files(VOID);
|
||||
PRIVATE int QSort_Comp_Func(const void *p1, const void *p2);
|
||||
PRIVATE VOID Sort_FileData_Table(VOID);
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* WWDOS_INIT -- Initialize the fileio WWS fileio system. *
|
||||
* *
|
||||
* *
|
||||
* INPUT: ULONG cachesize - size wanted for the cache. *
|
||||
* BYTE *filedat - NULL or name of filedata table file. *
|
||||
* BYTE *cdpath - NULL or secondary search path on a CD. *
|
||||
* *
|
||||
* OUTPUT: Returns all errors encountered or'd together. *
|
||||
* *
|
||||
* WARNINGS: User should call the WWDOS_Init function for all file *
|
||||
* initialization. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
FileInitErrorType cdecl WWDOS_Init(ULONG cachesize, BYTE *filedata, BYTE *cdpath)
|
||||
{
|
||||
// FileInitErrorType errors;
|
||||
unsigned errors ;
|
||||
|
||||
// This has not been completed yet, when it is, uncomment it and add errors.
|
||||
Install_Hard_Error_Handler () ;
|
||||
Get_Devices();
|
||||
|
||||
if (cachesize) {
|
||||
errors = Init_File_Cache(cachesize);
|
||||
} else {
|
||||
errors = FI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
errors = errors | Init_FileData_Table(filedata);
|
||||
|
||||
errors = errors | Set_Search_Drives(cdpath);
|
||||
|
||||
errors = errors | Preload_Files();
|
||||
|
||||
|
||||
return ( FileInitErrorType ) errors ;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* WWDOS_SHUTDOWN -- Clean up any things that needs to be in file syste to *
|
||||
* exit game. *
|
||||
* One could shut down the file system and open it back *
|
||||
* up with a different size cache or filetable. *
|
||||
* *
|
||||
* INPUT: NONE. *
|
||||
* *
|
||||
* OUTPUT: NONE. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
VOID cdecl WWDOS_Shutdown(VOID)
|
||||
{
|
||||
FileDataType *filedata; // Pointer to the current FileData.
|
||||
WORD file_handle;
|
||||
FileHandleType *filehandletable; // Pointer to the current file handle.
|
||||
|
||||
// Close all open files.
|
||||
filehandletable = FileHandleTable;
|
||||
for (file_handle = 0; file_handle < TABLE_MAX; file_handle++, filehandletable++) {
|
||||
if (!filehandletable->Empty) {
|
||||
Close_File(file_handle);
|
||||
}
|
||||
}
|
||||
|
||||
// Free the file cache heap.
|
||||
if (FileCacheHeap) {
|
||||
|
||||
// Get a pointer to the current filedata.
|
||||
if (FileDataPtr) {
|
||||
filedata = FileDataPtr;
|
||||
} else {
|
||||
filedata = FileData;
|
||||
}
|
||||
|
||||
while(filedata->Name && filedata->Name[0]) {
|
||||
filedata->Ptr = NULL;
|
||||
filedata++;
|
||||
}
|
||||
|
||||
Free(FileCacheHeap);
|
||||
FileCacheHeap = NULL;
|
||||
}
|
||||
|
||||
// Free up the file data.
|
||||
if (FileDataPtr != FileData) {
|
||||
Free(FileDataPtr);
|
||||
}
|
||||
FileDataPtr = NULL;
|
||||
|
||||
chdir(StartPath);
|
||||
ibm_setdisk(*StartPath - 'A');
|
||||
|
||||
// This has not been completed yet, when it is, uncomment it and add errors.
|
||||
Remove_Hard_Error_Handler();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* INIT_FILE_CACHE -- Initializes and allocs the file cache heap. *
|
||||
* *
|
||||
* INPUT: ULONG cachesize - size of heap cache.. *
|
||||
* *
|
||||
* OUTPUT: FileInitErrorType error code. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
PRIVATE FileInitErrorType cdecl Init_File_Cache(ULONG cachesize)
|
||||
{
|
||||
// Allocate and initialize the file cache heap.
|
||||
if (FileCacheHeap) {
|
||||
return (FI_CACHE_ALREADY_INIT);
|
||||
}
|
||||
|
||||
if ((Ram_Free(MEM_NORMAL) >= cachesize)) {
|
||||
FileCacheHeap = Alloc(cachesize, MEM_NORMAL);
|
||||
Mem_Init(FileCacheHeap, cachesize);
|
||||
}
|
||||
|
||||
if (!FileCacheHeap) {
|
||||
return (FI_CACHE_TOO_BIG);
|
||||
}
|
||||
|
||||
return (FI_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* INIT_FILEDATA_TABLE -- Initializes or reads in FileData Table. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: FileInitErrorType error code. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/13/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
PRIVATE FileInitErrorType cdecl Init_FileData_Table(BYTE const *filename)
|
||||
{
|
||||
WORD fd;
|
||||
ULONG fsize;
|
||||
FileDataType *ptr;
|
||||
WORD index;
|
||||
BYTE fname[13];
|
||||
|
||||
/*
|
||||
** Inialize the file handle table to reflect no files open.
|
||||
*/
|
||||
for (index = 0; index < TABLE_MAX; index++) {
|
||||
FileHandleTable[index].Empty = TRUE;
|
||||
}
|
||||
|
||||
// Set up our FileData ptr to be the initial FileData table.
|
||||
FileDataPtr = FileData;
|
||||
|
||||
// Sort the filedata table.
|
||||
// This needs to be done even if we load it off disk since the initial file data
|
||||
// table might contain a filename.
|
||||
Sort_FileData_Table();
|
||||
|
||||
// If there is a file name, then the filedata table will be loaded from disk.
|
||||
if (filename) {
|
||||
if (!Find_File(filename)) {
|
||||
return (FI_FILEDATA_FILE_NOT_FOUND);
|
||||
}
|
||||
fd = Open_File(filename, READ);
|
||||
|
||||
fsize = File_Size(fd);
|
||||
|
||||
if ((Ram_Free(MEM_NORMAL) < fsize)) {
|
||||
Close_File(fd);
|
||||
return (FI_FILEDATA_TOO_BIG);
|
||||
}
|
||||
|
||||
// Allocate some system memory.
|
||||
// Setup the new FileDataPtr and this time.
|
||||
FileDataPtr = ptr = (FileDataType *) Alloc(fsize, MEM_NORMAL);
|
||||
|
||||
// Load the file up into memory.
|
||||
Read_File(fd, FileDataPtr, fsize);
|
||||
Close_File(fd);
|
||||
|
||||
// Process the filetable. The filenames need their pointers adjusted.
|
||||
// At this time we will also count the number of files and number of PAK files.
|
||||
NumPAKFiles = NumFiles = 0;
|
||||
|
||||
// Make sure that the file name will have a NUL at the end.
|
||||
fname[12] = 0;
|
||||
while(TRUE) {
|
||||
// Have we reached the end of the list?
|
||||
if (!ptr->Name) break;
|
||||
|
||||
// Adjust the name pointer to point the the correct area.
|
||||
ptr->Name = (BYTE *)FileDataPtr + (LONG) ptr->Name;
|
||||
|
||||
// Count up weather it is a PAK file or a normal file.
|
||||
if (!NumFiles && strstr((char *) ptr->Name, (char *) ".PAK")) {
|
||||
NumPAKFiles++;
|
||||
|
||||
// Mark that it has been processed so that Open_File() will not do it.
|
||||
ptr->Flag |= FILEF_PROCESSED;
|
||||
|
||||
} else {
|
||||
NumFiles++;
|
||||
}
|
||||
|
||||
// Next record.
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return (FI_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Set_Search_Drives -- Sets up the CDRom and HardDrive paths. *
|
||||
* *
|
||||
* INPUT: BYTE *cdpath - path of data files on a CD. *
|
||||
* Should pass in NULL for non CD products. *
|
||||
* *
|
||||
* OUTPUT: FileInitErrorType error code. *
|
||||
* Varibable defined: *
|
||||
* ExecPath = Full path of EXE file. *
|
||||
* StartPath = Directory user started in. *
|
||||
* DataPath = secondary search path (typically CD-ROM). *
|
||||
* Note: format of paths is "C:\PATH" *
|
||||
* *
|
||||
* WARNINGS: The cdpath may be overiden by a "-CD<path>" command line *
|
||||
* arguement that specifies another drive (HARD or CD) and path *
|
||||
* where the data resides. Whenever a file is opened, it checks *
|
||||
* the startup drive first, then the CD search path if the first *
|
||||
* search was unsuccessful. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/14/1993 SB : Created. *
|
||||
* 04/19/1994 SKB : Mods for 32 bit library. *
|
||||
*=========================================================================*/
|
||||
PRIVATE FileInitErrorType cdecl Set_Search_Drives( BYTE *cdpath )
|
||||
{
|
||||
BYTE *ptr;
|
||||
|
||||
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
// NOTE: THIS IS WRONG, THIS IS NOT THE WAY TO GET THE EXE's PATH.
|
||||
// Locate the executable.
|
||||
strcpy(ExecPath, _argv[0]);
|
||||
|
||||
// Find the very last '\' on the path.
|
||||
ptr = strrchr((char *) ExecPath, (int) '\\');
|
||||
#else
|
||||
ptr = NULL;
|
||||
#endif
|
||||
|
||||
// Remove the exe name to just have the path.
|
||||
if (ptr == NULL) {
|
||||
*ExecPath = 0;
|
||||
}
|
||||
else {
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
// Did the user specify a second path?
|
||||
ptr = Find_Argv("-CD");
|
||||
|
||||
// If so, set the data path to that.
|
||||
if (ptr) {
|
||||
strcpy(DataPath, ptr + 3);
|
||||
}
|
||||
// Otherwise check to see if there is a CD-Rom drive.
|
||||
else {
|
||||
if (cdpath && *cdpath) {
|
||||
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
UseCD = GetCDDrive();
|
||||
#else
|
||||
UseCD = FALSE;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
UseCD = FALSE;
|
||||
}
|
||||
|
||||
// If so, set the Drive to it and find out if any directories.
|
||||
if ( UseCD ) {
|
||||
strcpy( DataPath, "A:" );
|
||||
strcat( DataPath, cdpath);
|
||||
*DataPath = 'A'+UseCD;
|
||||
}
|
||||
// If not, set the Data path to the execacutable path.
|
||||
else {
|
||||
strcpy(DataPath, ExecPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Finnally, set the starting path.
|
||||
getcwd(StartPath, XMAXPATH);
|
||||
|
||||
// Make sure they are all uppercase.
|
||||
strupr(StartPath);
|
||||
strupr(DataPath);
|
||||
strupr(ExecPath);
|
||||
|
||||
// Change directories to the secondary search path (DataPath).
|
||||
if (*DataPath && chdir(DataPath)) {
|
||||
return (FI_SEARCH_PATH_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Lastley, Make sure we are in the startup directory. This will overide
|
||||
// the secondary data path if they are on the same drive.
|
||||
if (chdir(StartPath)) {
|
||||
return (FI_STARTUP_PATH_NOT_FOUND);
|
||||
}
|
||||
|
||||
return (FI_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* PRELOAD_FILES -- Loads files marked with FILEF_PRELOAD into cache. *
|
||||
* *
|
||||
* *
|
||||
* INPUT: none. *
|
||||
* *
|
||||
* OUTPUT: FileInitErrorType error code. *
|
||||
* *
|
||||
* WARNINGS: The FileData must be initialized and the file heap initialized*
|
||||
* in order for this to work. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
PRIVATE FileInitErrorType cdecl Preload_Files(VOID)
|
||||
{
|
||||
FileDataType *filedata; // Working file data table pointer.
|
||||
BOOL oldflag; // Previous file flag.
|
||||
|
||||
if (!FileDataPtr) {
|
||||
return (FI_FILETABLE_NOT_INIT);
|
||||
}
|
||||
|
||||
if (!FileCacheHeap) {
|
||||
return (FI_NO_CACHE_FOR_PRELOAD);
|
||||
}
|
||||
|
||||
/*
|
||||
** Make all files flagged to be made resident at startup, resident.
|
||||
*/
|
||||
filedata = FileDataPtr;
|
||||
|
||||
while (filedata->Name && strlen(filedata->Name)) {
|
||||
if (filedata->Flag & FILEF_PRELOAD) {
|
||||
|
||||
oldflag = filedata->Flag;
|
||||
filedata->Flag |= FILEF_RESIDENT; // Make it resident.
|
||||
filedata->Flag &= ~FILEF_FLUSH; // Don't purge on Close_File.
|
||||
|
||||
Close_File(Open_File(filedata->Name, READ));
|
||||
|
||||
filedata->Flag &= ~(FILEF_RESIDENT|FILEF_FLUSH); // Clear bits.
|
||||
filedata->Flag |= oldflag & (FILEF_RESIDENT|FILEF_FLUSH); // Restore bits.
|
||||
|
||||
}
|
||||
filedata++;
|
||||
}
|
||||
return (FI_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* SORT_FILEDATA_TABLE -- Sorts the FileData table that is in memory. *
|
||||
* *
|
||||
* INPUT: NONE *
|
||||
* *
|
||||
* OUTPUT: NONE. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/13/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
PRIVATE int QSort_Comp_Func(const void *p1, const void *p2)
|
||||
{
|
||||
return(strcmp(((FileDataType*)p1)->Name, ((FileDataType*)p2)->Name));
|
||||
}
|
||||
PRIVATE VOID Sort_FileData_Table(VOID)
|
||||
{
|
||||
/*
|
||||
** Sort the filetable it but keep the pack file indexes correct.
|
||||
*/
|
||||
|
||||
/*
|
||||
** The number of pak files in the file table.
|
||||
*/
|
||||
NumPAKFiles = 0;
|
||||
strupr(FileData[NumPAKFiles].Name);
|
||||
while (strstr((char *) FileData[NumPAKFiles].Name, (char *) ".PAK")) {
|
||||
strupr(FileData[NumPAKFiles].Name);
|
||||
NumPAKFiles++;
|
||||
}
|
||||
|
||||
/*
|
||||
** Count the remaining files within the file table.
|
||||
*/
|
||||
NumFiles = 0;
|
||||
while(FileData[NumFiles+NumPAKFiles].Name && FileData[NumFiles+NumPAKFiles].Name[0]) {
|
||||
strupr(FileData[NumFiles+NumPAKFiles].Name);
|
||||
NumFiles++;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sort the file entries (past the pak files).
|
||||
*/
|
||||
if (NumFiles) {
|
||||
qsort(&FileData[NumPAKFiles], NumFiles, sizeof(FileDataType), QSort_Comp_Func);
|
||||
}
|
||||
}
|
||||
|
||||
151
WIN32LIB/SRCDEBUG/FILEIO.CPP
Normal file
151
WIN32LIB/SRCDEBUG/FILEIO.CPP
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : FILEIO.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : August 21, 1991 *
|
||||
* *
|
||||
* Last Update : September 13, 1993 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#include <dos.h>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
WORD ibm_getdisk(VOID)
|
||||
{
|
||||
unsigned disk;
|
||||
|
||||
CallingDOSInt++;
|
||||
// disk = getdisk();
|
||||
_dos_getdrive ( & disk ) ;
|
||||
CallingDOSInt--;
|
||||
return(disk-1);
|
||||
}
|
||||
|
||||
WORD ibm_setdisk(WORD drive)
|
||||
{
|
||||
// WORD disk;
|
||||
unsigned disk ;
|
||||
|
||||
CallingDOSInt++;
|
||||
// disk = setdisk(drive);
|
||||
_dos_setdrive ( drive+1 , & disk ) ;
|
||||
CallingDOSInt--;
|
||||
return(disk);
|
||||
}
|
||||
|
||||
WORD ibm_close(WORD handle)
|
||||
{
|
||||
WORD success;
|
||||
|
||||
CallingDOSInt++;
|
||||
success = close(handle);
|
||||
CallingDOSInt--;
|
||||
return(success);
|
||||
}
|
||||
|
||||
WORD ibm_unlink(BYTE const *name)
|
||||
{
|
||||
WORD success;
|
||||
|
||||
CallingDOSInt++;
|
||||
success = unlink(name);
|
||||
CallingDOSInt--;
|
||||
return(success);
|
||||
}
|
||||
|
||||
LONG ibm_lseek(WORD handle, LONG offset, WORD where)
|
||||
{
|
||||
LONG new_offset;
|
||||
|
||||
CallingDOSInt++;
|
||||
new_offset = lseek(handle, offset, where);
|
||||
CallingDOSInt--;
|
||||
return(new_offset);
|
||||
}
|
||||
|
||||
UWORD ibm_read(WORD handle, VOID *ptr, UWORD bytes)
|
||||
{
|
||||
UWORD bytes_read;
|
||||
|
||||
CallingDOSInt++;
|
||||
bytes_read = read(handle, ptr, bytes);
|
||||
CallingDOSInt--;
|
||||
return(bytes_read);
|
||||
}
|
||||
|
||||
UWORD ibm_write(WORD handle, VOID *ptr, UWORD bytes)
|
||||
{
|
||||
UWORD bytes_written;
|
||||
|
||||
CallingDOSInt++;
|
||||
bytes_written = write(handle, ptr, bytes);
|
||||
CallingDOSInt--;
|
||||
return(bytes_written);
|
||||
}
|
||||
|
||||
WORD ibm_open(BYTE const *name, UWORD mode, WORD attrib)
|
||||
{
|
||||
WORD handle;
|
||||
|
||||
CallingDOSInt++;
|
||||
handle = open(name, mode, attrib);
|
||||
CallingDOSInt--;
|
||||
return(handle);
|
||||
}
|
||||
|
||||
WORD ibm_chdir(BYTE const *path)
|
||||
{
|
||||
WORD retval;
|
||||
|
||||
CallingDOSInt++;
|
||||
retval = chdir(path);
|
||||
CallingDOSInt--;
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
388
WIN32LIB/SRCDEBUG/FILELIB.CPP
Normal file
388
WIN32LIB/SRCDEBUG/FILELIB.CPP
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : FILEIO Library support routines. *
|
||||
* *
|
||||
* File Name : FILELIB.C *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : April 11, 1994 *
|
||||
* *
|
||||
* Last Update : April 11, 1994 [SKB] *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Notes: This file contains private functions to the fileio system. *
|
||||
* While these functions may be used by any module in the fileio *
|
||||
* system, they cannot be used by a user program. For this reason *
|
||||
* they are put into this module. *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Cache_File -- Attempts to cache file in XMS if flags set. *
|
||||
* Do_IO_Error -- Performs a non-recoverable error message display. *
|
||||
* Do_Open_Error -- Does an error message that could return. *
|
||||
* Is_Handle_Valid -- Determines validity of the specified file handle. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#ifndef WWMEM_H
|
||||
#include <wwmem.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <sys\stat.h>
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* DO_ERROR -- Does an error message that could return. *
|
||||
* *
|
||||
* This routine displays a file error message and unless the player *
|
||||
* presses <ESC>, it will return. If the player presses <ESC>, then *
|
||||
* it will terminate the program. *
|
||||
* *
|
||||
* INPUT: error -- Error message number. *
|
||||
* *
|
||||
* filename -- File name that the error occured on. *
|
||||
* *
|
||||
* OUTPUT: TRUE/FALSE; Should the process be repeated? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/09/1991 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
#pragma argsused
|
||||
WORD cdecl Do_Open_Error(FileErrorType errormsgnum, BYTE const *file_name)
|
||||
{
|
||||
BYTE *ptr=NULL; // Working file name pointer (just name and extension).
|
||||
|
||||
/*
|
||||
** Since the file name may include a path, we must extract the true
|
||||
** file name from the given string.
|
||||
*/
|
||||
if (file_name) {
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
ptr = strrchr((char *) file_name, (int) '\\');
|
||||
#else
|
||||
ptr = NULL;
|
||||
#endif
|
||||
if (ptr) {
|
||||
ptr++;
|
||||
} else {
|
||||
ptr = (BYTE *) file_name;
|
||||
}
|
||||
}
|
||||
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
strupr(ptr);
|
||||
return (IO_Error(errormsgnum, ptr));
|
||||
#else
|
||||
return(0);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* DO_IO_ERROR -- Performs a non-recoverable error message display. *
|
||||
* *
|
||||
* This routine will perform a non-recoverable file error message *
|
||||
* display. It is called when an error is detected that has no *
|
||||
* recovery or retry process defined. *
|
||||
* *
|
||||
* INPUT: errornum -- Error number detected. *
|
||||
* *
|
||||
* filename -- Name of the file that caused the error. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/09/1991 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
#pragma argsused
|
||||
VOID cdecl Do_IO_Error(FileErrorType errormsgnum, BYTE const *filename)
|
||||
{
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
(VOID)IO_Error(errormsgnum, filename);
|
||||
#endif
|
||||
#if(TRUE)
|
||||
Prog_End();
|
||||
exit((int)errormsgnum);
|
||||
#else
|
||||
Program_End();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Read_File_With_Recovery -- read the same file on another directory if an error *
|
||||
* occurs. *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/16/1993 QY : Created. *
|
||||
*=========================================================================*/
|
||||
LONG cdecl Read_File_With_Recovery( WORD handle, VOID *buf, UWORD bytes )
|
||||
{
|
||||
WORD newhandle;
|
||||
LONG bytes_read;
|
||||
|
||||
do {
|
||||
Hard_Error_Occured = 0;
|
||||
|
||||
// Make sure we are in the right path.
|
||||
CHANGEDIR( DataPath );
|
||||
|
||||
// open the same file
|
||||
newhandle = Open_File( FileHandleTable[ handle ].Name, FileHandleTable[ handle ].Mode );
|
||||
Seek_File( newhandle, FileHandleTable[ handle ].Pos, SEEK_SET );
|
||||
|
||||
// dos close the old file
|
||||
FILECLOSE( FileHandleTable[ handle ].Handle );
|
||||
|
||||
// copy FileHandleTable[ newhandle ] to FileHandleTable[ handle ]
|
||||
Mem_Copy( &FileHandleTable[ newhandle ], &FileHandleTable[ handle ],
|
||||
( ULONG ) sizeof( FileHandleTable[ newhandle ] ) );
|
||||
|
||||
// delete FileHandleTable[newhandle]
|
||||
|
||||
FileHandleTable[ newhandle ].Empty = TRUE;
|
||||
|
||||
// continue reading file
|
||||
bytes_read = ( LONG ) FILEREAD( FileHandleTable[ handle ].Handle, buf, bytes );
|
||||
|
||||
// if still error, do it again; else return the number of bytes read
|
||||
if ( !Hard_Error_Occured ) {
|
||||
return( bytes_read );
|
||||
}
|
||||
if (!Do_Open_Error(COULD_NOT_OPEN, FileHandleTable[ handle ].Name)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
} while (CHANGEDIR( DataPath ));
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Open_File_With_Recovery -- open the same file on another directory *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/16/1993 QY : Created. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Open_File_With_Recovery( BYTE const *file_name, UWORD mode )
|
||||
{
|
||||
WORD handle;
|
||||
|
||||
Hard_Error_Occured = FALSE;
|
||||
handle = FILEOPEN(file_name, mode);
|
||||
|
||||
// Do not return if there was a HardError and Using a CD and we are looking at
|
||||
// the CD.
|
||||
if (!Hard_Error_Occured || !UseCD || (ibm_getdisk() != (*DataPath - 'A'))) {
|
||||
return (handle);
|
||||
}
|
||||
|
||||
#if DEBUGPRINT
|
||||
Mono_Print(file_name); Mono_Print(":OPENERROR ");
|
||||
#endif
|
||||
|
||||
Hard_Error_Occured = 0;
|
||||
|
||||
// It is possible that the CD has been poped out and put back in, let us
|
||||
// change there and then try again.
|
||||
ibm_setdisk(*DataPath - 'A');
|
||||
CHANGEDIR( DataPath );
|
||||
|
||||
// open the same file
|
||||
handle = FILEOPEN( file_name, mode );
|
||||
|
||||
// if still error, do it again; else return the dos handle
|
||||
if ( !Hard_Error_Occured ) {
|
||||
return( handle );
|
||||
}
|
||||
|
||||
Hard_Error_Occured = 0;
|
||||
return (FILEOPENERROR);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CACHE_FILE -- Attempts to cache file in XMS if flags set. *
|
||||
* *
|
||||
* *
|
||||
* INPUT: WORD index - the index of the file in the FileData table. *
|
||||
* WORD file_handle - WWS file handle of file. *
|
||||
* *
|
||||
* OUTPUT: BOOL : was it cached? *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1993 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
BOOL cdecl Cache_File(WORD index, WORD file_handle)
|
||||
{
|
||||
LONG filesize; // Size of the memory block needed.
|
||||
LONG freecache; // Amount of free XMS.
|
||||
FileDataType *filedata = NULL;
|
||||
FileDataType hold;
|
||||
FileHandleType *filehandletable;
|
||||
WORD flag; // Type of system memory to cache file.
|
||||
WORD file;
|
||||
|
||||
// Only files in the file table can be cached.
|
||||
if (index == ERROR) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Setup our pointer to the file we may want to cache.
|
||||
filedata = &FileDataPtr[index];
|
||||
|
||||
// Should this be cached, and is it not yet cached?
|
||||
if ((filedata->Flag & (FILEF_RESIDENT|FILEF_PRELOAD)) && !filedata->Ptr) {
|
||||
|
||||
filesize = filedata->Size;
|
||||
|
||||
/*
|
||||
** If there is o room to cache the file, then turn off its cache file.
|
||||
*/
|
||||
if (filesize > Mem_Pool_Size(FileCacheHeap)) {
|
||||
|
||||
// Remove resident flags so that it will not keep trying to cache itself
|
||||
// since there will never be enough room for it.
|
||||
filedata->Flag &= ~(FILEF_PRELOAD|FILEF_KEEP|FILEF_RESIDENT|FILEF_FLUSH);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Go through freeing files until there is enouph space in the
|
||||
// memory pool.
|
||||
while (filesize > Mem_Avail(FileCacheHeap)) {
|
||||
VOID *node;
|
||||
|
||||
// Get the oldest non used file pointer.
|
||||
node = Mem_Find_Oldest(FileCacheHeap);
|
||||
|
||||
// If non was found, sorry no room for the new file.
|
||||
if (!node) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
// Get a pointer to the structure for convenience.
|
||||
filedata = &FileDataPtr[Mem_Get_ID(node)];
|
||||
|
||||
// Free it from the heap and update the file system so it knows that
|
||||
// the file is no longer in memory.
|
||||
Mem_Free(FileCacheHeap, filedata->Ptr);
|
||||
filedata->Ptr = NULL;
|
||||
}
|
||||
|
||||
|
||||
// If there is not a big enough space we will have to take garbage
|
||||
// collection hit. (OUCH!!!!!!)
|
||||
if (filesize > Mem_Largest_Avail(FileCacheHeap)) {
|
||||
Unfragment_File_Cache();
|
||||
}
|
||||
|
||||
// Make sure we have a big enough space and if so, put the file into memory.
|
||||
if (filesize < Mem_Largest_Avail(FileCacheHeap)) {
|
||||
|
||||
// Get some pointers to save code space and time.
|
||||
filehandletable = &FileHandleTable[file_handle];
|
||||
filedata = &FileDataPtr[index];
|
||||
|
||||
// Alloc the buffer in our file cache, then read the file in.
|
||||
filedata->Ptr = Mem_Alloc(FileCacheHeap, filesize, index);
|
||||
|
||||
// Extra check - it should not fail.
|
||||
if (!filedata->Ptr) return(FALSE);
|
||||
|
||||
// Mark it so that it never comes back as Oldest used.
|
||||
Mem_In_Use(filedata->Ptr);
|
||||
|
||||
// Get the file into memory.
|
||||
Read_File(file_handle, filedata->Ptr, filesize);
|
||||
|
||||
// reset the read index from the above read.
|
||||
filehandletable->Pos = 0L;
|
||||
|
||||
// This makes caching inner pak file possible. No longer is the
|
||||
// PAK'd file based off the parent file.
|
||||
filehandletable->Start = 0;
|
||||
|
||||
// Close the parent file. Remove it's open count.
|
||||
if (filedata->Flag & FILEF_PACKED) {
|
||||
FileDataType p_hold;
|
||||
FileDataType *parent;
|
||||
|
||||
parent = &FileDataPtr[filedata->Disk];
|
||||
parent->OpenCount--;
|
||||
}
|
||||
FILECLOSE(filehandletable->Handle);
|
||||
filehandletable->Handle = 0;
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// The file was not cached, let the caller know.
|
||||
return (FALSE);
|
||||
}
|
||||
41
WIN32LIB/SRCDEBUG/FILESTUB.CPP
Normal file
41
WIN32LIB/SRCDEBUG/FILESTUB.CPP
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : wwlib32 *
|
||||
* *
|
||||
* File Name : FILESTUB.CPP *
|
||||
* *
|
||||
* Programmer : Bill Randolph *
|
||||
* *
|
||||
* Start Date : May 3, 1994 *
|
||||
* *
|
||||
* Last Update : May 3, 1994 [BR] *
|
||||
* *
|
||||
* This module is a temorary stub that contains IO_Error. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#include "wwstd.h"
|
||||
#include "file.h"
|
||||
|
||||
WORD Text_IO_Error(FileErrorType, BYTE const *){return FALSE;}
|
||||
WORD (*IO_Error)(FileErrorType, BYTE const *) = Text_IO_Error;
|
||||
|
||||
/************************* End of filestub.cpp *****************************/
|
||||
669
WIN32LIB/SRCDEBUG/FILLQUAD.ASM
Normal file
669
WIN32LIB/SRCDEBUG/FILLQUAD.ASM
Normal file
@@ -0,0 +1,669 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Library *
|
||||
;* *
|
||||
;* File Name : FILLQUAD.ASM *
|
||||
;* *
|
||||
;* Programmer : Ian M. Leslie *
|
||||
;* *
|
||||
;* Start Date : August 11, 1994 *
|
||||
;* *
|
||||
;* Last Update : August 30, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Fill_Quad -- Flood fills an arbitrary convex quadrilateral *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
SLOT_VACANT EQU 80008000h
|
||||
NULL EQU 0h
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* VVC::FILL_QUAD -- Flood fills an arbitrary convex quadrilateral *
|
||||
;* *
|
||||
;* INPUT: DWORD this_object - associated graphic viewport *
|
||||
;* DWORD span_buff - pointer to span array *
|
||||
;* DWORD x0_pixel - the zeroth x pixel position *
|
||||
;* DWORD y0_pixel - the zeroth y pixel position *
|
||||
;* DWORD x1_pixel - the first x pixel position *
|
||||
;* DWORD y1_pixel - the first y pixel position *
|
||||
;* DWORD x2_pixel - the second x pixel position *
|
||||
;* DWORD y2_pixel - the second y pixel position *
|
||||
;* DWORD x3_pixel - the third x pixel position *
|
||||
;* DWORD y3_pixel - the third y pixel position *
|
||||
;* DWORD color - the color of the quad to fill *
|
||||
;* *
|
||||
;* Bounds Checking: Compares quad points with the graphic viewport it *
|
||||
;* has been assigned to. *
|
||||
;* *
|
||||
;* Rasterization Rules: FILL_QUAD is designed to be used within a quad *
|
||||
;* mesh. There is no pixel overlapping or stitching *
|
||||
;* effects at shared borders. FILL_QUAD is NOT *
|
||||
;* recommended for isolated quads. * *
|
||||
;* HISTORY: *
|
||||
;* 08/11/1994 IML : Created. *
|
||||
;* 08/26/1994 IML : Various optimizations. *
|
||||
;* 08/30/1994 IML : Added rasterization rules for shared borders. *
|
||||
;*=========================================================================*
|
||||
PROC Buffer_Fill_Quad C NEAR
|
||||
USES eax,ebx,ecx,edx,esi,edi
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Define the arguments that the function takes.
|
||||
;*==================================================================
|
||||
ARG this_object:DWORD ; associated graphic viewport
|
||||
ARG span_buff:DWORD ; pointer to span array
|
||||
ARG x0_pixel:DWORD ; the zeroth x pixel position
|
||||
ARG y0_pixel:DWORD ; the zeroth y pixel position
|
||||
ARG x1_pixel:DWORD ; the first x pixel position
|
||||
ARG y1_pixel:DWORD ; the first y pixel position
|
||||
ARG x2_pixel:DWORD ; the second x pixel position
|
||||
ARG y2_pixel:DWORD ; the second y pixel position
|
||||
ARG x3_pixel:DWORD ; the third x pixel position
|
||||
ARG y3_pixel:DWORD ; the third y pixel position
|
||||
ARG color:DWORD ; the color of the quad
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Define the local variables that we will use on the stack.
|
||||
;*==================================================================
|
||||
LOCAL clip_min_x:DWORD ; boundary of viewport
|
||||
LOCAL clip_max_x:DWORD ;
|
||||
LOCAL clip_min_y:DWORD ;
|
||||
LOCAL clip_max_y:DWORD ;
|
||||
LOCAL clip_var:DWORD
|
||||
LOCAL left_clip_base:DWORD:2 ; storage for additional edges
|
||||
LOCAL left_clip_index:DWORD ; generated by clipping
|
||||
LOCAL right_clip_base:DWORD:2 ;
|
||||
LOCAL right_clip_index:DWORD ;
|
||||
LOCAL scanline_min:DWORD ; vertical extent of quad
|
||||
LOCAL scanline_max:DWORD
|
||||
LOCAL realignment:DWORD
|
||||
LOCAL bpr:DWORD ; bytes per row of associated buffer
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Extract essential GraphicViewPort info.
|
||||
;*==================================================================
|
||||
mov ebx,[this_object]
|
||||
mov eax,[(GraphicViewPort ebx).GVPXPos]
|
||||
mov [clip_min_x],eax
|
||||
mov eax,[(GraphicViewPort ebx).GVPYPos]
|
||||
mov [clip_min_y],eax
|
||||
mov eax,[(GraphicViewPort ebx).GVPWidth]
|
||||
mov [clip_max_x],eax
|
||||
add eax,[(GraphicViewPort ebx).GVPXAdd]
|
||||
add eax,[(GraphicViewPort ebx).GVPPitch]
|
||||
mov [bpr],eax
|
||||
mov eax,[(GraphicViewPort ebx).GVPHeight]
|
||||
mov [clip_max_y],eax
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Adjust top and right edges of viewport for rasterization rules.
|
||||
;*==================================================================
|
||||
dec [clip_max_y]
|
||||
dec [clip_min_y]
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Find the vertical extent of the quad BEFORE clipping.
|
||||
;* y0_pixel = y0, y1_pixel = y1, y2_pixel = y2, y3_pixel = y3
|
||||
;*==================================================================
|
||||
mov eax,[y0_pixel]
|
||||
cmp eax,[y1_pixel]
|
||||
jle short ??y1_not_smaller
|
||||
mov eax,[y1_pixel]
|
||||
|
||||
??y1_not_smaller:
|
||||
cmp eax,[y2_pixel]
|
||||
jle short ??y2_not_smaller
|
||||
mov eax,[y2_pixel]
|
||||
|
||||
??y2_not_smaller:
|
||||
cmp eax,[y3_pixel]
|
||||
jle short ??y3_not_smaller
|
||||
mov eax,[y3_pixel]
|
||||
|
||||
??y3_not_smaller:
|
||||
cmp eax,[clip_min_y]
|
||||
jge short ??no_clamp_min_min
|
||||
mov eax,[clip_min_y]
|
||||
|
||||
??no_clamp_min_min:
|
||||
cmp eax,[clip_max_y]
|
||||
jle short ??no_clamp_max_min
|
||||
mov eax,[clip_max_y]
|
||||
; scanline_min = MIN (y0, y1, y2, y3)
|
||||
??no_clamp_max_min: ; scanline_min = MAX (scanline_min, clip_min_y)
|
||||
mov [scanline_min],eax ; scanline_min = MIN (scanline_min, clip_max_y)
|
||||
|
||||
mov eax,[y0_pixel]
|
||||
cmp eax,[y1_pixel]
|
||||
jge short ??y1_not_greater
|
||||
mov eax,[y1_pixel]
|
||||
|
||||
??y1_not_greater:
|
||||
cmp eax,[y2_pixel]
|
||||
jge short ??y2_not_greater
|
||||
mov eax,[y2_pixel]
|
||||
|
||||
??y2_not_greater:
|
||||
cmp eax,[y3_pixel]
|
||||
jge short ??y3_not_greater
|
||||
mov eax,[y3_pixel]
|
||||
|
||||
??y3_not_greater:
|
||||
cmp eax,[clip_min_y]
|
||||
jge short ??no_clamp_min_max
|
||||
mov eax,[clip_min_y]
|
||||
|
||||
??no_clamp_min_max:
|
||||
cmp eax,[clip_max_y]
|
||||
jle short ??no_clamp_max_max
|
||||
mov eax,[clip_max_y]
|
||||
; scanline_max = MAX (y0, y1, y2, y3)
|
||||
??no_clamp_max_max: ; scanline_max = MAX (scanline_max, clip_min_y)
|
||||
mov [scanline_max],eax ; scanline_max = MIN (scanline_max, clip_max_y)
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Initialize memory for spans.
|
||||
;*==================================================================
|
||||
sub eax,[scanline_min]
|
||||
je ??abort_fill_quad ; don't render quads with zero height
|
||||
mov ebx,eax
|
||||
mov eax,[span_buff] ; check span_buff for NULL ptr
|
||||
cmp eax,NULL
|
||||
je ??abort_fill_quad
|
||||
sal ebx,2
|
||||
|
||||
??span_initialize_loop:
|
||||
mov [DWORD PTR eax + ebx],SLOT_VACANT
|
||||
sub ebx,4
|
||||
jl short ??exit_span_initialize
|
||||
mov [DWORD PTR eax + ebx],SLOT_VACANT
|
||||
sub ebx,4
|
||||
jl short ??exit_span_initialize
|
||||
mov [DWORD PTR eax + ebx],SLOT_VACANT
|
||||
sub ebx,4
|
||||
jl short ??exit_span_initialize
|
||||
mov [DWORD PTR eax + ebx],SLOT_VACANT
|
||||
sub ebx,4
|
||||
jge short ??span_initialize_loop
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Clip and scan convert the four edges defining the quad.
|
||||
;*==================================================================
|
||||
??exit_span_initialize:
|
||||
mov [left_clip_index],0
|
||||
mov [right_clip_index],0
|
||||
|
||||
mov eax,[x0_pixel]
|
||||
mov ebx,[y0_pixel]
|
||||
mov ecx,[x1_pixel]
|
||||
mov edx,[y1_pixel]
|
||||
call NEAR PTR ??clip_and_scan_convert
|
||||
mov eax,[x1_pixel]
|
||||
mov ebx,[y1_pixel]
|
||||
mov ecx,[x2_pixel]
|
||||
mov edx,[y2_pixel]
|
||||
call NEAR PTR ??clip_and_scan_convert
|
||||
mov eax,[x2_pixel]
|
||||
mov ebx,[y2_pixel]
|
||||
mov ecx,[x3_pixel]
|
||||
mov edx,[y3_pixel]
|
||||
call NEAR PTR ??clip_and_scan_convert
|
||||
mov eax,[x3_pixel]
|
||||
mov ebx,[y3_pixel]
|
||||
mov ecx,[x0_pixel]
|
||||
mov edx,[y0_pixel]
|
||||
call NEAR PTR ??clip_and_scan_convert
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Scan convert up to 2 additional left and right vertical edges
|
||||
;* generated by the clipping process.
|
||||
;*==================================================================
|
||||
cmp [left_clip_index],0
|
||||
je short ??no_left_edge
|
||||
mov eax,[clip_min_x]
|
||||
mov ebx,[left_clip_base]
|
||||
mov ecx,eax
|
||||
mov edx,[left_clip_base + 4]
|
||||
call NEAR PTR ??scan_convert
|
||||
|
||||
??no_left_edge:
|
||||
cmp [right_clip_index],0
|
||||
je short ??no_right_edge
|
||||
mov eax,[clip_max_x]
|
||||
mov ebx,[right_clip_base]
|
||||
mov ecx,eax
|
||||
mov edx,[right_clip_base + 4]
|
||||
call NEAR PTR ??scan_convert
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Fill the quad with specified color. Use DWORD copies where
|
||||
;* appropriate.
|
||||
;*==================================================================
|
||||
??no_right_edge:
|
||||
mov eax,[this_object]
|
||||
mov edi,[(GraphicViewPort eax).GVPOffset]
|
||||
mov eax,[scanline_min] ; eax = scanline_min
|
||||
|
||||
mov ebx,[scanline_max]
|
||||
sub ebx,[scanline_min] ; ebx = span count
|
||||
|
||||
mov esi,[span_buff] ; esi = address of top span
|
||||
|
||||
mul [bpr]
|
||||
add edi,eax ; edi = address of top scanline
|
||||
; containing quad
|
||||
mov al,[BYTE PTR color] ; extend pixel color into eax ready
|
||||
mov ah,al ; for DWORD copies
|
||||
mov edx,eax
|
||||
shl eax,16
|
||||
mov ax,dx
|
||||
|
||||
cld ; only fill forwards
|
||||
|
||||
jmp ??skip_span ; rasterization rule: don't
|
||||
; render topmost span
|
||||
|
||||
??quad_fill_loop:
|
||||
cmp [DWORD PTR esi],SLOT_VACANT ; test for unused spans due to clipping
|
||||
je ??skip_span
|
||||
xor ecx,ecx
|
||||
xor edx,edx
|
||||
mov cx,[WORD PTR esi]
|
||||
mov dx,[WORD PTR esi + 2]
|
||||
sub ecx,edx
|
||||
push edi
|
||||
jns short ??not_negative_count
|
||||
add edi,ecx
|
||||
neg ecx ; ecx = span width
|
||||
|
||||
??not_negative_count:
|
||||
add edi,edx ; edi = address of start of span
|
||||
cmp ecx,OPTIMAL_BYTE_COPY ; does span width justify DWORD copies?
|
||||
jl short ??byte_copy
|
||||
mov edx,ecx
|
||||
mov ecx,edi
|
||||
and ecx,3 ; if (ecx == 0) edi is already
|
||||
jz short ??dword_copy_no_alignment ; DWORD aligned
|
||||
xor ecx,3
|
||||
inc ecx ; ecx = number of pixels before alignment
|
||||
sub edx,ecx
|
||||
rep stosb
|
||||
|
||||
??dword_copy_no_alignment:
|
||||
mov ecx,edx ; ecx = remaining pixels on span
|
||||
shr ecx,2 ; copy (ecx / 4) DWORDS
|
||||
rep stosd
|
||||
mov ecx,edx
|
||||
and ecx,3 ; ecx = remaining pixels on span
|
||||
|
||||
??byte_copy:
|
||||
rep stosb ; byte copy remaining pixels on span
|
||||
pop edi
|
||||
|
||||
??skip_span:
|
||||
add edi,[bpr] ; edi = address of start of next scanline
|
||||
add esi,4 ; esi = address of next span
|
||||
dec ebx
|
||||
jge short ??quad_fill_loop ; is span count >= 0?
|
||||
|
||||
??abort_fill_quad:
|
||||
ret
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* This is the section that "pushes" the edge into bounds.
|
||||
;* I have marked the section with PORTABLE start and end to signify
|
||||
;* how much of this routine is 100% portable between graphics modes.
|
||||
;* It was just as easy to have variables as it would be for constants
|
||||
;* so the global vars clip_min_x, clip_min_y, clip_max_x, clip_max_y
|
||||
;* are used to clip the edge (default is the screen).
|
||||
;* PORTABLE start.
|
||||
;*==================================================================
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Clip an edge against the viewport.
|
||||
;*==================================================================
|
||||
??clip_and_scan_convert:
|
||||
call NEAR PTR ??set_left_right_bits
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
mov edi,esi
|
||||
call NEAR PTR ??set_left_right_bits
|
||||
mov [clip_var],edi
|
||||
or [clip_var],esi
|
||||
jz ??clip_up_down ; trivial acceptance?
|
||||
test edi,esi
|
||||
jne ??exit ; trivial rejection?
|
||||
shl esi,2
|
||||
call [DWORD PTR cs:??clip_tbl+esi]
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
shl edi,2
|
||||
call [DWORD PTR cs:??clip_tbl+edi]
|
||||
|
||||
??clip_up_down:
|
||||
call NEAR PTR ??set_up_down_bits
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
mov edi,esi
|
||||
call NEAR PTR ??set_up_down_bits
|
||||
mov [clip_var],edi
|
||||
or [clip_var],esi
|
||||
jz ??scan_convert ; trivial acceptance?
|
||||
test edi,esi
|
||||
jne ??exit ; trivial rejection?
|
||||
shl esi,2
|
||||
call [DWORD PTR cs:??clip_tbl+esi]
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
shl edi,2
|
||||
call [DWORD PTR cs:??clip_tbl+edi]
|
||||
jmp ??scan_convert
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Subroutine table for clipping conditions.
|
||||
;*==================================================================
|
||||
??clip_tbl DD ??nada,??a_lft,??a_rgt,??nada
|
||||
DD ??a_up,??nada,??nada,??nada
|
||||
DD ??a_dwn
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Subroutines for clipping conditions.
|
||||
;*==================================================================
|
||||
??nada:
|
||||
retn
|
||||
|
||||
??a_up:
|
||||
mov esi,[clip_min_y]
|
||||
call NEAR PTR ??clip_vert
|
||||
retn
|
||||
|
||||
??a_dwn:
|
||||
mov esi,[clip_max_y]
|
||||
call NEAR PTR ??clip_vert
|
||||
retn
|
||||
|
||||
??a_lft:
|
||||
mov esi,[clip_min_x]
|
||||
call NEAR PTR ??clip_horiz
|
||||
push ebx
|
||||
mov esi,[left_clip_index]
|
||||
cmp ebx,[clip_min_y]
|
||||
jge ??no_left_min_clip
|
||||
mov ebx,[clip_min_y]
|
||||
|
||||
??no_left_min_clip:
|
||||
cmp ebx,[clip_max_y]
|
||||
jle ??no_left_max_clip
|
||||
mov ebx,[clip_max_y]
|
||||
|
||||
??no_left_max_clip:
|
||||
mov [left_clip_base + esi],ebx ; a left edge will be generated
|
||||
mov [left_clip_index],4 ; store off yb
|
||||
pop ebx
|
||||
retn
|
||||
|
||||
??a_rgt:
|
||||
mov esi,[clip_max_x]
|
||||
call NEAR PTR ??clip_horiz
|
||||
push ebx
|
||||
mov esi,[right_clip_index]
|
||||
cmp ebx,[clip_min_y]
|
||||
jge ??no_right_min_clip
|
||||
mov ebx,[clip_min_y]
|
||||
|
||||
??no_right_min_clip:
|
||||
cmp ebx,[clip_max_y]
|
||||
jle ??no_right_max_clip
|
||||
mov ebx,[clip_max_y]
|
||||
|
||||
??no_right_max_clip:
|
||||
mov [right_clip_base + esi],ebx ; a right edge will be generated
|
||||
mov [right_clip_index],4 ; store off yb
|
||||
pop ebx
|
||||
retn
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Clip a line against a horizontal edge at clip_y.
|
||||
;* (eax,ebx) = (xa,ya), (ecx,edx) = (xb,yb)
|
||||
;* xa' = xa+[(clip_y-ya)(xb-xa)/(yb-ya)]
|
||||
;* ya' = clip_y
|
||||
;*==================================================================
|
||||
??clip_vert:
|
||||
push edx
|
||||
push eax
|
||||
mov [clip_var],edx ; clip_var = yb
|
||||
sub [clip_var],ebx ; clip_var = (yb-ya)
|
||||
neg eax ; eax = -xa
|
||||
add eax,ecx ; eax = (xb-xa)
|
||||
mov edx,esi ; edx = clip_y
|
||||
sub edx,ebx ; edx = (clip_y-ya)
|
||||
imul edx ; eax = (clip_y-ya)(xb-xa)
|
||||
idiv [clip_var] ; eax = (clip_y-ya)(xb-xa)/(yb-ya)
|
||||
pop edx
|
||||
add eax,edx ; eax = xa+[(clip_y-ya)(xb-xa)/(yb-ya)]
|
||||
pop edx
|
||||
mov ebx,esi ; ebx = clip_y
|
||||
retn
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Clip a line against a vertical edge at clip_x.
|
||||
;* (eax,ebxx) = (xa,ya), (ecx,edxx) = (xb,yb)
|
||||
;* ya' = ya+[(clip_x-xa)(yb-ya)/(xb-xa)]
|
||||
;* xa' = clip_x
|
||||
;*==================================================================
|
||||
??clip_horiz:
|
||||
push edx
|
||||
mov [clip_var],ecx ; clip_var = xb
|
||||
sub [clip_var],eax ; clip_var = (xb-xa)
|
||||
sub edx,ebx ; edx = (yb-ya)
|
||||
neg eax ; eax = -xa
|
||||
add eax,esi ; eax = (clip_x-xa)
|
||||
imul edx ; eax = (clip_x-xa)(yb-ya)
|
||||
idiv [clip_var] ; eax = (clip_x-xa)(yb-ya)/(xb-xa)
|
||||
add ebx,eax ; ebx = ya+[(clip_x-xa)(yb-ya)/(xb-xa)]
|
||||
pop edx
|
||||
mov eax,esi ; eax = clip_x
|
||||
retn
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Set the condition bits for the subroutine table.
|
||||
;*==================================================================
|
||||
??set_left_right_bits:
|
||||
xor esi,esi
|
||||
cmp eax,[clip_min_x] ; if x >= left its not left
|
||||
jge short ??a_not_left
|
||||
or esi,1
|
||||
|
||||
??a_not_left:
|
||||
cmp eax,[clip_max_x] ; if x <= right its not right
|
||||
jle short ??a_not_right
|
||||
or esi,2
|
||||
|
||||
??a_not_right:
|
||||
retn
|
||||
|
||||
??set_up_down_bits:
|
||||
xor esi,esi
|
||||
cmp ebx,[clip_min_y] ; if y >= top its not up
|
||||
jge short ??a_not_up
|
||||
or esi,4
|
||||
|
||||
??a_not_up:
|
||||
cmp ebx,[clip_max_y] ; if y <= bottom its not down
|
||||
jle short ??a_not_down
|
||||
or esi,8
|
||||
|
||||
??a_not_down:
|
||||
retn
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* PORTABLE end.
|
||||
;*==================================================================
|
||||
|
||||
;*==================================================================
|
||||
;* Scan convert an edge.
|
||||
;* (eax,ebx) = (xa,ya), (ecx,edx) = (xb,yb)
|
||||
;*==================================================================
|
||||
??scan_convert:
|
||||
cmp ebx,edx
|
||||
je ??exit ; if (ya == yb) don't scan convert
|
||||
jl short ??no_swap ; if (ya < yb) swap vertices
|
||||
xchg eax,ecx
|
||||
xchg ebx,edx
|
||||
|
||||
??no_swap:
|
||||
sub edx,ebx ; edx = (yb - ya)
|
||||
sub ebx,[scanline_min]
|
||||
sal ebx,2
|
||||
add ebx,[span_buff] ; ebx = span_buff + 4(ya - clip_min_y)
|
||||
sub ecx,eax ; ecx = (xb - xa)
|
||||
je ??v_scan ; if the edge is vertical use a
|
||||
; special case routine
|
||||
push eax
|
||||
mov eax,ecx ; eax = (xb - xa)
|
||||
mov ecx,edx ; ecx = (yb - ya)
|
||||
sal edx,1
|
||||
mov [realignment],edx ; realignment = 2(yb - ya)
|
||||
cwd
|
||||
idiv cx
|
||||
cwde
|
||||
movsx edx,dx
|
||||
mov edi,eax ; edi = (xb - xa) / (yb - ya)
|
||||
mov esi,edx
|
||||
mov edx,ecx
|
||||
pop eax ; eax = xa
|
||||
neg edx ; edx = -(yb - ya)
|
||||
sal esi,1 ; esi = 2[(xb - xa) % (yb - ya)]
|
||||
jns short ??r_scan ; scan to the left or right?
|
||||
neg esi
|
||||
|
||||
;*==================================================================
|
||||
;* Edge scan conversion DDA moving down and to the left.
|
||||
;* eax = xpos, ebx = span to reference
|
||||
;*==================================================================
|
||||
cmp ebx,[span_buff]
|
||||
jg ??l_scan_convert
|
||||
|
||||
??l_scan_convert_loop:
|
||||
cmp [DWORD PTR ebx],SLOT_VACANT ; if the left slot of span is
|
||||
jne short ??l_next_slot ; vacant fill it with xpos
|
||||
mov [ebx],ax
|
||||
|
||||
??l_next_slot:
|
||||
mov [ebx + 2],ax ; otherwise fill the right slot
|
||||
; with xpos
|
||||
??l_scan_convert:
|
||||
dec ecx
|
||||
jl short ??exit
|
||||
add ebx,4
|
||||
add eax,edi
|
||||
add edx,esi
|
||||
jle short ??l_scan_convert_loop
|
||||
dec eax
|
||||
sub edx,[realignment]
|
||||
jmp ??l_scan_convert_loop
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Edge scan conversion DDA moving down and to the right.
|
||||
;* eax = xpos, ebx = span to reference
|
||||
;*==================================================================
|
||||
??r_scan:
|
||||
cmp ebx,[span_buff]
|
||||
jg ??r_scan_convert
|
||||
|
||||
??r_scan_convert_loop:
|
||||
cmp [DWORD PTR ebx],SLOT_VACANT ; if the left slot of span is
|
||||
jne short ??r_next_slot ; vacant fill it with xpos
|
||||
mov [ebx],ax
|
||||
|
||||
??r_next_slot:
|
||||
mov [ebx + 2],ax ; otherwise fill the right slot
|
||||
; with xpos
|
||||
??r_scan_convert:
|
||||
dec ecx
|
||||
jl short ??exit
|
||||
add ebx,4
|
||||
add eax,edi
|
||||
add edx,esi
|
||||
jle short ??r_scan_convert_loop
|
||||
inc eax
|
||||
sub edx,[realignment]
|
||||
jmp ??r_scan_convert_loop
|
||||
|
||||
|
||||
;*==================================================================
|
||||
;* Scan convert a vertical edge.
|
||||
;* eax = xpos, ebx = span to reference
|
||||
;*==================================================================
|
||||
??v_scan:
|
||||
cmp ebx,[span_buff]
|
||||
jg ??v_scan_convert
|
||||
|
||||
??v_scan_convert_loop:
|
||||
cmp [DWORD PTR ebx],SLOT_VACANT ; if the left slot of span is
|
||||
jne short ??v_next_slot ; vacant fill it with xpos
|
||||
mov [ebx],ax
|
||||
|
||||
??v_next_slot:
|
||||
mov [ebx + 2],ax ; otherwise fill the right slot
|
||||
; with xpos
|
||||
??v_scan_convert:
|
||||
add ebx,4
|
||||
dec edx
|
||||
jge ??v_scan_convert_loop
|
||||
|
||||
??exit:
|
||||
retn
|
||||
|
||||
ENDP Buffer_Fill_Quad
|
||||
|
||||
END
|
||||
275
WIN32LIB/SRCDEBUG/FILLRECT.ASM
Normal file
275
WIN32LIB/SRCDEBUG/FILLRECT.ASM
Normal file
@@ -0,0 +1,275 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : GraphicViewPortClass *
|
||||
;* *
|
||||
;* File Name : CLEAR.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil Gorrow *
|
||||
;* *
|
||||
;* Start Date : June 7, 1994 *
|
||||
;* *
|
||||
;* Last Update : June 7, 1994 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* GVPC::Fill_Rect -- draws a filled rectangle to a graphics buffer *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* GVPC::FILL_RECT -- Fills a rectangular region of a graphic view port *
|
||||
;* *
|
||||
;* INPUT: WORD the left hand x pixel position of region *
|
||||
;* WORD the upper x pixel position of region *
|
||||
;* WORD the right hand x pixel position of region *
|
||||
;* WORD the lower x pixel position of region *
|
||||
;* UBYTE the color (optional) to clear the view port to *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* NOTE: This function is optimized to handle viewport with no XAdd *
|
||||
;* value. It also handles DWORD aligning the destination *
|
||||
;* when speed can be gained by doing it. *
|
||||
;* HISTORY: *
|
||||
;* 06/07/1994 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
PROC Buffer_Fill_Rect C near
|
||||
USES eax,ebx,ecx,edx,esi,edi,ebp
|
||||
|
||||
;*===================================================================
|
||||
;* define the arguements that our function takes.
|
||||
;*===================================================================
|
||||
ARG this_object:DWORD ; this is a member function
|
||||
ARG x1_pixel:WORD
|
||||
ARG y1_pixel:WORD
|
||||
ARG x2_pixel:WORD
|
||||
ARG y2_pixel:WORD
|
||||
ARG color:BYTE ; what color should we clear to
|
||||
;*===================================================================
|
||||
; Define some locals so that we can handle things quickly
|
||||
;*===================================================================
|
||||
LOCAL VPwidth:DWORD ; the width of the viewport
|
||||
LOCAL VPheight:DWORD ; the height of the viewport
|
||||
LOCAL VPxadd:DWORD ; the additional x offset of viewport
|
||||
LOCAL VPbpr:DWORD ; the number of bytes per row of viewport
|
||||
|
||||
;*===================================================================
|
||||
;* save off the viewport characteristics on the stack
|
||||
;*===================================================================
|
||||
mov ebx,[this_object] ; get a pointer to viewport
|
||||
mov eax,[(GraphicViewPort ebx).GVPWidth] ; get width from viewport
|
||||
mov ecx,[(GraphicViewPort ebx).GVPHeight] ; get height from viewport
|
||||
mov edx,[(GraphicViewPort ebx).GVPXAdd] ; get xadd from viewport
|
||||
add edx,[(GraphicViewPort ebx).GVPPitch] ; extra pitch of direct draw surface
|
||||
mov [VPwidth],eax ; store the width of locally
|
||||
mov [VPheight],ecx
|
||||
mov [VPxadd],edx
|
||||
add eax,edx
|
||||
mov [VPbpr],eax
|
||||
|
||||
;*===================================================================
|
||||
;* move the important parameters into local registers
|
||||
;*===================================================================
|
||||
movsx eax,[x1_pixel]
|
||||
movsx ebx,[y1_pixel]
|
||||
movsx ecx,[x2_pixel]
|
||||
movsx edx,[y2_pixel]
|
||||
|
||||
;*===================================================================
|
||||
;* Convert the x2 and y2 pixel to a width and height
|
||||
;*===================================================================
|
||||
cmp eax,ecx
|
||||
jl ??no_swap_x
|
||||
xchg eax,ecx
|
||||
|
||||
??no_swap_x:
|
||||
sub ecx,eax
|
||||
cmp ebx,edx
|
||||
jl ??no_swap_y
|
||||
xchg ebx,edx
|
||||
??no_swap_y:
|
||||
sub edx,ebx
|
||||
inc ecx
|
||||
inc edx
|
||||
|
||||
;*===================================================================
|
||||
;* Bounds check source X.
|
||||
;*===================================================================
|
||||
cmp eax, [VPwidth] ; compare with the max
|
||||
jge ??out ; starts off screen, then later
|
||||
jb short ??sx_done ; if it's not negative, it's ok
|
||||
|
||||
;------ Clip source X to left edge of screen.
|
||||
add ecx, eax ; Reduce width (add in negative src X).
|
||||
xor eax, eax ; Clip to left of screen.
|
||||
??sx_done:
|
||||
|
||||
;*===================================================================
|
||||
;* Bounds check source Y.
|
||||
;*===================================================================
|
||||
cmp ebx, [VPheight] ; compare with the max
|
||||
jge ??out ; starts off screen, then later
|
||||
jb short ??sy_done ; if it's not negative, it's ok
|
||||
|
||||
;------ Clip source Y to top edge of screen.
|
||||
add edx, ebx ; Reduce height (add in negative src Y).
|
||||
xor ebx, ebx ; Clip to top of screen.
|
||||
|
||||
??sy_done:
|
||||
;*===================================================================
|
||||
;* Bounds check width versus width of source and dest view ports
|
||||
;*===================================================================
|
||||
push ebx ; save off ebx for later use
|
||||
mov ebx,[VPwidth] ; get the source width
|
||||
sub ebx, eax ; Maximum allowed pixel width (given coordinates).
|
||||
sub ebx, ecx ; Pixel width undershoot.
|
||||
jns short ??width_ok ; if not signed no adjustment necessary
|
||||
add ecx, ebx ; Reduce width to screen limits.
|
||||
|
||||
??width_ok:
|
||||
pop ebx ; restore ebx to old value
|
||||
|
||||
;*===================================================================
|
||||
;* Bounds check height versus height of source view port
|
||||
;*===================================================================
|
||||
push eax ; save of eax for later use
|
||||
mov eax, [VPheight] ; get the source height
|
||||
sub eax, ebx ; Maximum allowed pixel height (given coordinates).
|
||||
sub eax, edx ; Pixel height undershoot.
|
||||
jns short ??height_ok ; if not signed no adjustment necessary
|
||||
add edx, eax ; Reduce height to screen limits.
|
||||
??height_ok:
|
||||
pop eax ; restore eax to old value
|
||||
|
||||
;*===================================================================
|
||||
;* Perform the last minute checks on the width and height
|
||||
;*===================================================================
|
||||
or ecx,ecx
|
||||
jz ??out
|
||||
|
||||
or edx,edx
|
||||
jz ??out
|
||||
|
||||
cmp ecx,[VPwidth]
|
||||
ja ??out
|
||||
cmp edx,[VPheight]
|
||||
ja ??out
|
||||
|
||||
;*===================================================================
|
||||
;* Get the offset into the virtual viewport.
|
||||
;*===================================================================
|
||||
xchg edi,eax ; save off the contents of eax
|
||||
xchg esi,edx ; and edx for size test
|
||||
mov eax,ebx ; move the y pixel into eax
|
||||
mul [VPbpr] ; multiply by bytes per row
|
||||
add edi,eax ; add the result into the x position
|
||||
mov ebx,[this_object]
|
||||
add edi,[(GraphicViewPort ebx).GVPOffset]
|
||||
|
||||
mov edx,esi ; restore edx back to real value
|
||||
mov eax,ecx ; store total width in ecx
|
||||
sub eax,[VPwidth] ; modify xadd value to include clipped
|
||||
sub [VPxadd],eax ; width bytes (subtract a negative number)
|
||||
|
||||
;*===================================================================
|
||||
; Convert the color byte to a DWORD for fast storing
|
||||
;*===================================================================
|
||||
mov al,[color] ; get color to clear to
|
||||
mov ah,al ; extend across WORD
|
||||
mov ebx,eax ; extend across DWORD in
|
||||
shl eax,16 ; several steps
|
||||
mov ax,bx
|
||||
|
||||
;*===================================================================
|
||||
; If there is no row offset then adjust the width to be the size of
|
||||
; the entire viewport and adjust the height to be 1
|
||||
;*===================================================================
|
||||
mov esi,[VPxadd]
|
||||
or esi,esi ; set the flags for esi
|
||||
jnz ??row_by_row_aligned ; and act on them
|
||||
|
||||
xchg eax,ecx ; switch bit pattern and width
|
||||
mul edx ; multiply by edx to get size
|
||||
xchg eax,ecx ; switch size and bit pattern
|
||||
mov edx,1 ; only 1 line off view port size to do
|
||||
|
||||
;*===================================================================
|
||||
; Find out if we should bother to align the row.
|
||||
;*===================================================================
|
||||
??row_by_row_aligned:
|
||||
mov ebp,ecx ; width saved in ebp
|
||||
cmp ecx,OPTIMAL_BYTE_COPY ; is it worth aligning them?
|
||||
jl ??row_by_row ; if not then skip
|
||||
|
||||
;*===================================================================
|
||||
; Figure out the alignment offset if there is any
|
||||
;*===================================================================
|
||||
mov ebx,edi ; get output position
|
||||
and ebx,3 ; is there a remainder?
|
||||
jz ??aligned_loop ; if not we are aligned
|
||||
xor ebx,3 ; find number of align bytes
|
||||
inc ebx ; this number is off by one
|
||||
sub ebp,ebx ; subtract from width
|
||||
|
||||
;*===================================================================
|
||||
; Now that we have the alignment offset copy each row
|
||||
;*===================================================================
|
||||
??aligned_loop:
|
||||
mov ecx,ebx ; get number of bytes to align
|
||||
rep stosb ; and move them over
|
||||
mov ecx,ebp ; get number of aligned bytes
|
||||
shr ecx,2 ; convert to DWORDS
|
||||
rep stosd ; and move them over
|
||||
mov ecx,ebp ; get number of aligned bytes
|
||||
and ecx,3 ; find the remainder
|
||||
rep stosb ; and move it over
|
||||
add edi,esi ; fix the line offset
|
||||
dec edx ; decrement the height
|
||||
jnz ??aligned_loop ; if more to do than do it
|
||||
jmp ??exit ; we are all done
|
||||
|
||||
;*===================================================================
|
||||
; If not enough bytes to bother aligning copy each line across a byte
|
||||
; at a time.
|
||||
;*===================================================================
|
||||
??row_by_row:
|
||||
mov ecx,ebp ; get total width in bytes
|
||||
rep stosb ; store the width
|
||||
add edi,esi ; handle the xadd
|
||||
dec edx ; decrement the height
|
||||
jnz ??row_by_row ; if any left then next line
|
||||
??out:
|
||||
??exit:
|
||||
ret
|
||||
ENDP Buffer_Fill_Rect
|
||||
|
||||
END
|
||||
90
WIN32LIB/SRCDEBUG/FINDARGV.CPP
Normal file
90
WIN32LIB/SRCDEBUG/FINDARGV.CPP
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: g:/library/wwlib32/misc/rcs/findargv.cpp 1.2 1994/04/22 10:29:28 scott_bowen Exp $ */
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : findargv *
|
||||
* *
|
||||
* File Name : findargv.C *
|
||||
* *
|
||||
* Programmer : Jeff Wilson *
|
||||
* *
|
||||
* Start Date : January 14, 1993 *
|
||||
* *
|
||||
* Last Update : May 20, 1993 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Find_Argv -- Checks to see if string is in arguement *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "wwstd.h"
|
||||
#include <dos.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Find_Argv -- Checks to see if string is in arguement *
|
||||
* *
|
||||
* INPUT: char *str - string to search for. *
|
||||
* *
|
||||
* OUTPUT: NULL if not found else pointer to string. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/14/1993 SB : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
//static char command [ 256 ] ;
|
||||
#pragma on (argsused)
|
||||
char * __cdecl Find_Argv(char const)
|
||||
{
|
||||
return (NULL);
|
||||
|
||||
|
||||
#ifdef NOT_FOR_WIN95
|
||||
char * __cdecl Find_Argv(char const *str)
|
||||
{
|
||||
char * ptr ;
|
||||
static startup_flag = 0 ;
|
||||
|
||||
if ( ! startup_flag )
|
||||
{
|
||||
startup_flag = 1 ;
|
||||
getcmd ( command ) ;
|
||||
}
|
||||
|
||||
if ( ! strlen(str) ) return NULL ;
|
||||
return strstr ( command , str ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
312
WIN32LIB/SRCDEBUG/FINDFILE.CPP
Normal file
312
WIN32LIB/SRCDEBUG/FINDFILE.CPP
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : FINDFILE.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : August 21, 1991 *
|
||||
* *
|
||||
* Last Update : September 29, 1993 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Find_File_Index -- Finds the FileTable index number for a given file. *
|
||||
* Find_File -- Checks if a file is immediatly available. *
|
||||
* Get_FileData -- Gets a pointer back to the correct file. *
|
||||
* Find_File -- Checks if a file is immediatly available. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef _FILE_H
|
||||
#include "_file.h"
|
||||
#endif
|
||||
|
||||
#include <direct.h>
|
||||
#include <dos.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <search.h>
|
||||
#include <sys\stat.h>
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FIND_FILE -- Checks if a file is immediatly available. *
|
||||
* *
|
||||
* Use this function to determine if a file is immediatly available. *
|
||||
* This routine will NOT request for the proper disk to be inserted *
|
||||
* if the file could not be found. Use File_Exists for that feature. *
|
||||
* The Westwood file I/O system does NOT have to be initialized as *
|
||||
* a prerequisit to using this function. *
|
||||
* *
|
||||
* INPUT: file_name -- Name of the file to check. *
|
||||
* *
|
||||
* OUTPUT: Returns the disk number that the file exits on (A=1, B=2, etc) *
|
||||
* *
|
||||
* WARNINGS: This sets the current drive to the drive that contains the *
|
||||
* specified file (if it is found). *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/14/1991 JLB : Created. *
|
||||
* 03/14/1992 JLB : Modified for Amiga compatability. *
|
||||
* 01/11/1993 SKB : Modified for CD-ROM searches. *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Find_File(BYTE const *file_name)
|
||||
{
|
||||
FileDataType *filedata = NULL;
|
||||
WORD index; // File index (if any).
|
||||
WORD disk; // Disk number of file (if in filetable).
|
||||
|
||||
/*
|
||||
** If the filename is invalid then it errors out as if the file wasn't
|
||||
** found (naturally).
|
||||
*/
|
||||
if (!file_name) return(FALSE);
|
||||
|
||||
/*
|
||||
** Determine if the file has a file table entry. If it does, then
|
||||
** special checks and processing must occur.
|
||||
** Also, if it is in memory, return with it.
|
||||
*/
|
||||
index = Find_File_Index(file_name);
|
||||
filedata = &FileDataPtr[index];
|
||||
|
||||
if (index != ERROR) {
|
||||
|
||||
// If the file is currently cached, return TRUE that it was found.
|
||||
if (filedata->Ptr) {
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Always check the current directory for the file. Only if it can't
|
||||
** be found are furthur measures required.
|
||||
*/
|
||||
DiskNumber = ERROR; // This indicates file exists in current directory.
|
||||
|
||||
|
||||
#if (LIB_CDROM)
|
||||
ibm_setdisk(*StartPath - 'A');
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Check the current directory by attempting to open with READ access.
|
||||
*/
|
||||
{
|
||||
WORD handle;
|
||||
|
||||
CallingDOSInt++;
|
||||
handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
|
||||
CallingDOSInt--;
|
||||
if (handle != ERROR)
|
||||
{
|
||||
// WORD d;
|
||||
unsigned d ;
|
||||
|
||||
CallingDOSInt++;
|
||||
close(handle);
|
||||
// d = getdisk();
|
||||
_dos_getdrive ( & d) ;
|
||||
CallingDOSInt--;
|
||||
return(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (index != ERROR) {
|
||||
|
||||
disk = filedata->Disk;
|
||||
/*
|
||||
** If the file is in a packed file, then search for the packed file
|
||||
** instead of the specified one.
|
||||
*/
|
||||
if (index != ERROR && (filedata->Flag & FILEF_PACKED)) {
|
||||
filedata = &FileDataPtr[disk];
|
||||
return (Find_File(filedata->Name));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** It could not be found on the current drive, so search the other
|
||||
** drives if allowed to do so.
|
||||
*/
|
||||
if (!MultiDriveSearch) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
#if (LIB_CDROM)
|
||||
// If we were unable to find the file on the hard drive, change
|
||||
// drives to the CD rom drive and see if it is there.
|
||||
ibm_setdisk(*DataPath - 'A');
|
||||
|
||||
{
|
||||
WORD handle;
|
||||
|
||||
Hard_Error_Occured = 0;
|
||||
|
||||
handle = Open_File_With_Recovery( file_name, MODE_OLDFILE );
|
||||
|
||||
if (handle != FILEOPENERROR) {
|
||||
FILECLOSE(handle);
|
||||
return(ibm_getdisk() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ibm_setdisk(*StartPath - 'A');
|
||||
return (FALSE);
|
||||
#else
|
||||
|
||||
{
|
||||
WORD start_drive; // Original current drive number.
|
||||
|
||||
/*
|
||||
** Record the current drive for restoring later in case of failure.
|
||||
*/
|
||||
CallingDOSInt++;
|
||||
start_drive = getdisk();
|
||||
CallingDOSInt--;
|
||||
|
||||
/*
|
||||
** Sweep backward from the last real drive to the first, looking for the
|
||||
** file on each in turn.
|
||||
*/
|
||||
for (index = MaxDevice; index != -1; index--) {
|
||||
if (Is_Device_Real(index)) {
|
||||
CallingDOSInt++;
|
||||
setdisk(index);
|
||||
CallingDOSInt--;
|
||||
|
||||
{
|
||||
WORD handle;
|
||||
|
||||
CallingDOSInt++;
|
||||
handle = open(file_name, O_RDONLY | O_BINARY, S_IREAD);
|
||||
CallingDOSInt--;
|
||||
if (handle != ERROR) {
|
||||
CallingDOSInt++;
|
||||
close(handle);
|
||||
CallingDOSInt--;
|
||||
DiskNumber = index+1;
|
||||
return (DiskNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CallingDOSInt++;
|
||||
setdisk(start_drive);
|
||||
CallingDOSInt--;
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FIND_FILE_INDEX -- Finds the FileTable index number for a given file. *
|
||||
* *
|
||||
* This function searches the FileTable and returns with the index of *
|
||||
* the matching file. If the file doesn't exist in the table, then *
|
||||
* ERROR is returned. It does not care about case. *
|
||||
* *
|
||||
* INPUT: filename -- Pointer to the filename to check. *
|
||||
* *
|
||||
* OUTPUT: Returns with the index into the FileTable. If the file does *
|
||||
* not exist in the file table, then ERROR is returned. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/09/1991 JLB : Created. *
|
||||
* 06/11/1993 JLB : Sorts and binary searches the file table. *
|
||||
*=========================================================================*/
|
||||
PRIVATE int Comp_Func(const void *p1, const void *p2)
|
||||
{
|
||||
return(strcmp((char *) ((FileDataType*)p1)->Name, (char *) ((FileDataType*)p2)->Name));
|
||||
}
|
||||
WORD cdecl Find_File_Index(BYTE const *filename)
|
||||
{
|
||||
FileDataType *filedata; // File entry pointer.
|
||||
FileDataType key; // Working file data type var.
|
||||
|
||||
/*
|
||||
** Perform a binary search on the presorted filetable.
|
||||
*/
|
||||
if (filename) {
|
||||
|
||||
filedata = NULL;
|
||||
key.Name = (BYTE *) strupr((char *)filename);
|
||||
if (strstr((char *)key.Name, (char *)".PAK")) {
|
||||
|
||||
/*
|
||||
** If the FileData table was not loaded from the disk then the PAK files are
|
||||
** not sorted so Perform a linear search for the pak files.
|
||||
** Otherwise the files are sorted so speed things up by doing a bsearch.
|
||||
*/
|
||||
if (FileData == FileDataPtr) {
|
||||
filedata = (FileDataType *) lfind(&key, FileDataPtr, (size_t *) &NumPAKFiles, sizeof(FileDataType), Comp_Func);
|
||||
}
|
||||
else {
|
||||
filedata = (FileDataType *)bsearch(&key, FileDataPtr, NumPAKFiles, sizeof(FileDataType), Comp_Func);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Perform a binary search for the regular files.
|
||||
*/
|
||||
filedata = (FileDataType *)bsearch(&key, &FileDataPtr[NumPAKFiles], NumFiles, sizeof(FileDataType), Comp_Func);
|
||||
}
|
||||
|
||||
// Return the element in the array if file was found in table.
|
||||
if (filedata) {
|
||||
return (filedata - FileDataPtr);
|
||||
//return ((WORD)((((LONG)filedata) - ((LONG)FileDataPtr)) / sizeof(FileDataType)));
|
||||
}
|
||||
}
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
141
WIN32LIB/SRCDEBUG/FONT.CPP
Normal file
141
WIN32LIB/SRCDEBUG/FONT.CPP
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : LIBRARY *
|
||||
* *
|
||||
* File Name : FONT.C *
|
||||
* *
|
||||
* Programmer : David Dettmer *
|
||||
* *
|
||||
* Last Update : July 20, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Char_Pixel_Width -- Return pixel width of a character. *
|
||||
* String_Pixel_Width -- Return pixel width of a string of characters. *
|
||||
* Get_Next_Text_Print_XY -- Calculates X and Y given ret value from Text_P*
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "font.h"
|
||||
#include <malloc.h>
|
||||
#include <dos.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <sys\stat.h>
|
||||
#include <string.h>
|
||||
#include <wwstd.h>
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CHAR_PIXEL_WIDTH -- Return pixel width of a character. *
|
||||
* *
|
||||
* Retreives the pixel width of a character from the font width block. *
|
||||
* *
|
||||
* INPUT: Character. *
|
||||
* *
|
||||
* OUTPUT: Pixel width of a string of characters. *
|
||||
* *
|
||||
* WARNINGS: Set_Font must have been called first. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/31/1992 DRD : Created. *
|
||||
* 06/30/1994 SKB : Converted to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
int __cdecl Char_Pixel_Width(char chr)
|
||||
{
|
||||
int width;
|
||||
|
||||
width = (unsigned char)*(FontWidthBlockPtr + (unsigned char)chr) + FontXSpacing;
|
||||
|
||||
return(width);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* STRING_PIXEL_WIDTH -- Return pixel width of a string of characters. *
|
||||
* *
|
||||
* Calculates the pixel width of a string of characters. This uses *
|
||||
* the font width block for the widths. *
|
||||
* *
|
||||
* INPUT: Pointer to string of characters. *
|
||||
* *
|
||||
* OUTPUT: Pixel width of a string of characters. *
|
||||
* *
|
||||
* WARNINGS: Set_Font must have been called first. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/30/1992 DRD : Created. *
|
||||
* 01/31/1992 DRD : Use Char_Pixel_Width. *
|
||||
* 06/30/1994 SKB : Converted to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
unsigned int __cdecl String_Pixel_Width(char const *string)
|
||||
{
|
||||
WORD width; // Working accumulator of string width.
|
||||
WORD largest = 0; // Largest recorded width of the string.
|
||||
|
||||
if (!string) return(0);
|
||||
|
||||
width = 0;
|
||||
while (*string) {
|
||||
if (*string == '\r') {
|
||||
string++;
|
||||
largest = MAX(largest, width);
|
||||
width = 0;
|
||||
} else {
|
||||
width += Char_Pixel_Width(*string++); // add each char's width
|
||||
}
|
||||
}
|
||||
largest = MAX(largest, width);
|
||||
return(largest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GET_NEXT_TEXT_PRINT_XY -- Calculates X and Y given ret value from Text_P*
|
||||
* *
|
||||
* *
|
||||
* INPUT: VVPC& vp - viewport that was printed to. *
|
||||
* unsigned long offset - offset that Text_Print returned. *
|
||||
* INT *x - x return value. *
|
||||
* INT *y - y return value. *
|
||||
* *
|
||||
* OUTPUT: x and y are set. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/20/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
VOID __cdecl Get_Next_Text_Print_XY(GraphicViewPortClass& gp, unsigned long offset, INT *x, INT *y)
|
||||
{
|
||||
INT buffwidth;
|
||||
|
||||
if (offset) {
|
||||
buffwidth = gp.Get_Width() + gp.Get_XAdd();
|
||||
offset -= gp.Get_Offset();
|
||||
*x = offset % buffwidth;
|
||||
*y = offset / buffwidth;
|
||||
} else {
|
||||
*x = *y = 0;
|
||||
}
|
||||
}
|
||||
106
WIN32LIB/SRCDEBUG/FTPUTPIX.ASM
Normal file
106
WIN32LIB/SRCDEBUG/FTPUTPIX.ASM
Normal file
@@ -0,0 +1,106 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : GraphicViewPortClass *
|
||||
;* *
|
||||
;* File Name : GETPIXEL.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil Gorrow *
|
||||
;* *
|
||||
;* Start Date : June 7, 1994 *
|
||||
;* *
|
||||
;* Last Update : June 7, 1994 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* VVPC::Buffer_Get_Pixel -- get the colour of a pixel at given coords *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* VVPC::GET_PIXEL -- Gets a pixel from the current view port *
|
||||
;* *
|
||||
;* INPUT: WORD the x pixel on the screen. *
|
||||
;* WORD the y pixel on the screen. *
|
||||
;* *
|
||||
;* OUTPUT: UBYTE the pixel at the specified location *
|
||||
;* *
|
||||
;* WARNING: If pixel is to be placed outside of the viewport then *
|
||||
;* this routine will abort. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/07/1994 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
PROC Buffer_Get_Pixel C near
|
||||
USES ebx,ecx,edx,edi
|
||||
|
||||
ARG this_object:DWORD ; this is a member function
|
||||
ARG x_pixel:DWORD ; x position of pixel to set
|
||||
ARG y_pixel:DWORD ; y position of pixel to set
|
||||
|
||||
;*===================================================================
|
||||
; Get the viewport information and put bytes per row in ecx
|
||||
;*===================================================================
|
||||
mov ebx,[this_object] ; get a pointer to viewport
|
||||
xor eax,eax
|
||||
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
|
||||
mov ecx,[(GraphicViewPort ebx).GVPHeight] ; edx = height of viewport
|
||||
mov edx,[(GraphicViewPort ebx).GVPWidth] ; ecx = width of viewport
|
||||
|
||||
;*===================================================================
|
||||
; Verify that the X pixel offset if legal
|
||||
;*===================================================================
|
||||
mov eax,[x_pixel] ; find the x position
|
||||
cmp eax,edx ; is it out of bounds
|
||||
jae short ??exit ; if so then get out
|
||||
add edi,eax ; otherwise add in offset
|
||||
|
||||
;*===================================================================
|
||||
; Verify that the Y pixel offset if legal
|
||||
;*===================================================================
|
||||
mov eax,[y_pixel] ; get the y position
|
||||
cmp eax,ecx ; is it out of bounds
|
||||
jae ??exit ; if so then get out
|
||||
add edx,[(GraphicViewPort ebx).GVPXAdd] ; otherwise find bytes per row
|
||||
add edx,[(GraphicViewPort ebx).GVPPitch] ; otherwise find bytes per row
|
||||
mul edx ; offset = bytes per row * y
|
||||
add edi,eax ; add it into the offset
|
||||
|
||||
;*===================================================================
|
||||
; Write the pixel to the screen
|
||||
;*===================================================================
|
||||
xor eax,eax ; clear the word
|
||||
mov al,[edi] ; read in the pixel
|
||||
??exit:
|
||||
ret
|
||||
ENDP Buffer_Get_Pixel
|
||||
|
||||
END
|
||||
711
WIN32LIB/SRCDEBUG/GBUFFER.CPP
Normal file
711
WIN32LIB/SRCDEBUG/GBUFFER.CPP
Normal file
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : GBUFFER.CPP *
|
||||
* *
|
||||
* Programmer : Phil W. Gorrow *
|
||||
* *
|
||||
* Start Date : May 3, 1994 *
|
||||
* *
|
||||
* Last Update : October 9, 1995 [] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* VVPC::VirtualViewPort -- Default constructor for a virtual viewport *
|
||||
* VVPC:~VirtualViewPortClass -- Destructor for a virtual viewport *
|
||||
* VVPC::Clear -- Clears a graphic page to correct color *
|
||||
* VBC::VideoBufferClass -- Lowlevel constructor for video buffer class *
|
||||
* GVPC::Change -- Changes position and size of a Graphic View Port *
|
||||
* VVPC::Change -- Changes position and size of a Video View Port *
|
||||
* Set_Logic_Page -- Sets LogicPage to new buffer *
|
||||
* GBC::DD_Init -- Inits a direct draw surface for a GBC *
|
||||
* GBC::Init -- Core function responsible for initing a GBC *
|
||||
* GBC::Lock -- Locks a Direct Draw Surface *
|
||||
* GBC::Unlock -- Unlocks a direct draw surface *
|
||||
* GBC::GraphicBufferClass -- Default constructor (requires explicit init)*
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef GBUFFER_H
|
||||
#include "gbuffer.h"
|
||||
#include "misc.h"
|
||||
#endif
|
||||
#pragma inline
|
||||
|
||||
int TotalLocks;
|
||||
BOOL AllowHardwareBlitFills = TRUE;
|
||||
|
||||
|
||||
//int CacheAllowed;
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GVPC::GRAPHICVIEWPORTCLASS -- Constructor for basic view port class *
|
||||
* m *
|
||||
* INPUT: GraphicBufferClass * gbuffer - buffer to attach to *
|
||||
* int x - x offset into buffer *
|
||||
* int y - y offset into buffer *
|
||||
* int w - view port width in pixels *
|
||||
* int h - view port height in pixels *
|
||||
* *
|
||||
* OUTPUT: Constructors may not have a return value *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/09/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicViewPortClass::GraphicViewPortClass(GraphicBufferClass *gbuffer, int x, int y, int w, int h) :
|
||||
LockCount(0),
|
||||
GraphicBuff(NULL)
|
||||
{
|
||||
Attach(gbuffer, x, y, w, h);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* GVPC::GRAPHICVIEWPORTCLASS -- Default constructor for view port class *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/09/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicViewPortClass::GraphicViewPortClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* GVPC::~GRAPHICVIEWPORTCLASS -- Destructor for GraphicViewPortClass *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: A destructor may not return a value. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/10/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicViewPortClass::~GraphicViewPortClass(void)
|
||||
{
|
||||
Offset = 0;
|
||||
Width = 0; // Record width of Buffer
|
||||
Height = 0; // Record height of Buffer
|
||||
XAdd = 0; // Record XAdd of Buffer
|
||||
XPos = 0; // Record XPos of Buffer
|
||||
YPos = 0; // Record YPos of Buffer
|
||||
Pitch = 0; // Record width of Buffer
|
||||
IsDirectDraw = FALSE;
|
||||
LockCount = 0;
|
||||
GraphicBuff = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* GVPC::ATTACH -- Attaches a viewport to a buffer class *
|
||||
* *
|
||||
* INPUT: GraphicBufferClass *g_buff - pointer to gbuff to attach to *
|
||||
* int x - x position to attach to *
|
||||
* int y - y position to attach to *
|
||||
* int w - width of the view port *
|
||||
* int h - height of the view port *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/10/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
void GraphicViewPortClass::Attach(GraphicBufferClass *gbuffer, int x, int y, int w, int h)
|
||||
{
|
||||
/*======================================================================*/
|
||||
/* Can not attach a Graphic View Port if it is actually the physical */
|
||||
/* representation of a Graphic Buffer. */
|
||||
/*======================================================================*/
|
||||
if (this == Get_Graphic_Buffer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*======================================================================*/
|
||||
/* Verify that the x and y coordinates are valid and placed within the */
|
||||
/* physical buffer. */
|
||||
/*======================================================================*/
|
||||
if (x < 0) // you cannot place view port off
|
||||
x = 0; // the left edge of physical buf
|
||||
if (x >= gbuffer->Get_Width()) // you cannot place left edge off
|
||||
x = gbuffer->Get_Width() - 1; // the right edge of physical buf
|
||||
if (y < 0) // you cannot place view port off
|
||||
y = 0; // the top edge of physical buf
|
||||
if (y >= gbuffer->Get_Height()) // you cannot place view port off
|
||||
y = gbuffer->Get_Height() - 1; // bottom edge of physical buf
|
||||
|
||||
/*======================================================================*/
|
||||
/* Adjust the width and height of necessary */
|
||||
/*======================================================================*/
|
||||
if (x + w > gbuffer->Get_Width()) // if the x plus width is larger
|
||||
w = gbuffer->Get_Width() - x; // than physical, fix width
|
||||
|
||||
if (y + h > gbuffer->Get_Height()) // if the y plus height is larger
|
||||
h = gbuffer->Get_Height() - y; // than physical, fix height
|
||||
|
||||
/*======================================================================*/
|
||||
/* Get a pointer to the top left edge of the buffer. */
|
||||
/*======================================================================*/
|
||||
Offset = gbuffer->Get_Offset() + ((gbuffer->Get_Width()+gbuffer->Get_Pitch()) * y) + x;
|
||||
|
||||
/*======================================================================*/
|
||||
/* Copy over all of the variables that we need to store. */
|
||||
/*======================================================================*/
|
||||
XPos = x;
|
||||
YPos = y;
|
||||
XAdd = gbuffer->Get_Width() - w;
|
||||
Width = w;
|
||||
Height = h;
|
||||
Pitch = gbuffer->Get_Pitch();
|
||||
GraphicBuff = gbuffer;
|
||||
IsDirectDraw= gbuffer->IsDirectDraw;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GVPC::CHANGE -- Changes position and size of a Graphic View Port *
|
||||
* *
|
||||
* INPUT: int the new x pixel position of the graphic view port *
|
||||
* int the new y pixel position of the graphic view port *
|
||||
* int the new width of the viewport in pixels *
|
||||
* int the new height of the viewport in pixels *
|
||||
* *
|
||||
* OUTPUT: BOOL whether the Graphic View Port could be sucessfully *
|
||||
* resized. *
|
||||
* *
|
||||
* WARNINGS: You may not resize a Graphic View Port which is derived *
|
||||
* from a Graphic View Port Buffer, *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/14/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
BOOL GraphicViewPortClass::Change(int x, int y, int w, int h)
|
||||
{
|
||||
/*======================================================================*/
|
||||
/* Can not change a Graphic View Port if it is actually the physical */
|
||||
/* representation of a Graphic Buffer. */
|
||||
/*======================================================================*/
|
||||
if (this == Get_Graphic_Buffer()) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*======================================================================*/
|
||||
/* Since there is no allocated information, just re-attach it to the */
|
||||
/* existing graphic buffer as if we were creating the */
|
||||
/* GraphicViewPort. */
|
||||
/*======================================================================*/
|
||||
Attach(Get_Graphic_Buffer(), x, y, w, h);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GBC::DD_INIT -- Inits a direct draw surface for a GBC *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/09/1995 : Created. *
|
||||
*=========================================================================*/
|
||||
void GraphicBufferClass::DD_Init(GBC_Enum flags)
|
||||
{
|
||||
//
|
||||
// Create the direct draw surface description
|
||||
//
|
||||
memset (&VideoSurfaceDescription , 0 , sizeof ( VideoSurfaceDescription ));
|
||||
|
||||
VideoSurfaceDescription.dwSize = sizeof( VideoSurfaceDescription );
|
||||
VideoSurfaceDescription.dwFlags = DDSD_CAPS;
|
||||
VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
|
||||
|
||||
if (!(flags & GBC_VISIBLE)) {
|
||||
VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
VideoSurfaceDescription.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
|
||||
VideoSurfaceDescription.dwHeight = Height;
|
||||
VideoSurfaceDescription.dwWidth = Width;
|
||||
}
|
||||
|
||||
//
|
||||
// Need to set the DDSCAPS_MODEX flag if we want a 320 wide mode
|
||||
//
|
||||
if ( Width == 320 ) {
|
||||
VideoSurfaceDescription.ddsCaps.dwCaps |= DDSCAPS_MODEX;
|
||||
}
|
||||
|
||||
//
|
||||
// Call CreateSurface
|
||||
//
|
||||
DirectDrawObject->CreateSurface( &VideoSurfaceDescription , &VideoSurfacePtr , NULL);
|
||||
AllSurfaces.Add_DD_Surface (VideoSurfacePtr);
|
||||
|
||||
if ( GBC_VISIBLE & flags ){
|
||||
PaletteSurface=VideoSurfacePtr;
|
||||
}
|
||||
|
||||
Allocated = FALSE; // even if system alloced, dont flag it cuz
|
||||
// we dont want it freed.
|
||||
IsDirectDraw = TRUE; // flag it as a video surface
|
||||
Offset = NOT_LOCKED; // flag it as unavailable for reading or writing
|
||||
LockCount = 0; // surface is not locked
|
||||
}
|
||||
|
||||
|
||||
void GraphicBufferClass::Attach_DD_Surface (GraphicBufferClass * attach_buffer)
|
||||
{
|
||||
VideoSurfacePtr->AddAttachedSurface (attach_buffer->Get_DD_Surface());
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GBC::INIT -- Core function responsible for initing a GBC *
|
||||
* *
|
||||
* INPUT: int - the width in pixels of the GraphicBufferClass *
|
||||
* int - the heigh in pixels of the GraphicBufferClass *
|
||||
* void * - pointer to user supplied buffer (system will *
|
||||
* allocate space if buffer is NULL) *
|
||||
* long - size of the user provided buffer *
|
||||
* GBC_Enum - flags if this is defined as a direct draw *
|
||||
* surface *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/09/1995 : Created. *
|
||||
*=========================================================================*/
|
||||
void GraphicBufferClass::Init(int w, int h, void *buffer, long size, GBC_Enum flags)
|
||||
{
|
||||
Size = size; // find size of physical buffer
|
||||
Width = w; // Record width of Buffer
|
||||
Height = h; // Record height of Buffer
|
||||
|
||||
//
|
||||
// If the surface we are creating is a direct draw object then
|
||||
// we need to do a direct draw init. Otherwise we will do
|
||||
// a normal alloc.
|
||||
//
|
||||
if (flags & (GBC_VIDEOMEM | GBC_VISIBLE)) {
|
||||
DD_Init(flags);
|
||||
} else {
|
||||
if (buffer) { // if buffer is specified
|
||||
Buffer = (BYTE *)buffer; // point to it and mark
|
||||
Allocated = FALSE; // it as user allocated
|
||||
} else {
|
||||
if (!Size) Size = w*h;
|
||||
Buffer = new BYTE[Size]; // otherwise allocate it and
|
||||
Allocated = TRUE; // mark it system alloced
|
||||
}
|
||||
Offset = (long)Buffer; // Get offset to the buffer
|
||||
IsDirectDraw = FALSE;
|
||||
}
|
||||
|
||||
Pitch = 0; // Record width of Buffer
|
||||
XAdd = 0; // Record XAdd of Buffer
|
||||
XPos = 0; // Record XPos of Buffer
|
||||
YPos = 0; // Record YPos of Buffer
|
||||
GraphicBuff = this; // Get a pointer to our self
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* GBC::Un_Init -- releases the video surface belonging to this gbuffer *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 6/6/96 12:44PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
|
||||
void GraphicBufferClass::Un_Init (void)
|
||||
{
|
||||
if ( IsDirectDraw ){
|
||||
|
||||
if ( VideoSurfacePtr ){
|
||||
|
||||
while ( LockCount ){
|
||||
|
||||
if (VideoSurfacePtr->Unlock ( NULL ) == DDERR_SURFACELOST){
|
||||
if (Gbuffer_Focus_Loss_Function){
|
||||
Gbuffer_Focus_Loss_Function();
|
||||
}
|
||||
AllSurfaces.Restore_Surfaces();
|
||||
}
|
||||
}
|
||||
|
||||
AllSurfaces.Remove_DD_Surface (VideoSurfacePtr);
|
||||
VideoSurfacePtr->Release();
|
||||
VideoSurfacePtr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GBC::GRAPHICBUFFERCLASS -- Default constructor (requires explicit init) *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/09/1995 : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicBufferClass::GraphicBufferClass(void)
|
||||
{
|
||||
GraphicBuff = this; // Get a pointer to our self
|
||||
VideoSurfacePtr = NULL;
|
||||
memset(&VideoSurfaceDescription, 0, sizeof(DDSURFACEDESC));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GBC::GRAPHICBUFFERCLASS -- Constructor for fixed size buffers *
|
||||
* *
|
||||
* INPUT: long size - size of the buffer to create *
|
||||
* int w - width of buffer in pixels (default = 320) *
|
||||
* int h - height of buffer in pixels (default = 200) *
|
||||
* void *buffer - a pointer to the buffer if any (optional) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/13/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer, long size)
|
||||
{
|
||||
Init(w, h, buffer, size, GBC_NONE);
|
||||
}
|
||||
/*=========================================================================*
|
||||
* GBC::GRAPHICBUFFERCLASS -- inline constructor for GraphicBufferClass *
|
||||
* *
|
||||
* INPUT: int w - width of buffer in pixels (default = 320) *
|
||||
* int h - height of buffer in pixels (default = 200) *
|
||||
* void *buffer - a pointer to the buffer if any (optional) *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/03/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer)
|
||||
{
|
||||
Init(w, h, buffer, w * h, GBC_NONE);
|
||||
}
|
||||
|
||||
/*====================================================================================*
|
||||
* GBC::GRAPHICBUFFERCLASS -- contructor for GraphicsBufferClass with special flags *
|
||||
* *
|
||||
* INPUT: int w - width of buffer in pixels (default = 320) *
|
||||
* int h - height of buffer in pixels (default = 200) *
|
||||
* void *buffer - unused *
|
||||
* unsigned flags - flags for creation of special buffer types *
|
||||
* GBC_VISIBLE - buffer is a visible screen surface *
|
||||
* GBC_VIDEOMEM - buffer resides in video memory *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09-21-95 04:19pm ST : Created *
|
||||
*====================================================================================*/
|
||||
GraphicBufferClass::GraphicBufferClass(int w, int h, GBC_Enum flags)
|
||||
{
|
||||
Init(w, h, NULL, w * h, flags);
|
||||
}
|
||||
|
||||
/*=========================================================================*
|
||||
* GBC::~GRAPHICBUFFERCLASS -- Destructor for the graphic buffer class *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/03/1994 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicBufferClass::~GraphicBufferClass()
|
||||
{
|
||||
|
||||
//
|
||||
// Release the direct draw surface if it exists
|
||||
//
|
||||
Un_Init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* SET_LOGIC_PAGE -- Sets LogicPage to new buffer *
|
||||
* *
|
||||
* INPUT: GraphicBufferClass * the buffer we are going to set *
|
||||
* *
|
||||
* OUTPUT: GraphicBufferClass * the previous buffer type *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass *ptr)
|
||||
{
|
||||
GraphicViewPortClass *old = LogicPage;
|
||||
LogicPage = ptr;
|
||||
return(old);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* SET_LOGIC_PAGE -- Sets LogicPage to new buffer *
|
||||
* *
|
||||
* INPUT: GraphicBufferClass & the buffer we are going to set *
|
||||
* *
|
||||
* OUTPUT: GraphicBufferClass * the previous buffer type *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/23/1995 PWG : Created. *
|
||||
*=========================================================================*/
|
||||
GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass &ptr)
|
||||
{
|
||||
GraphicViewPortClass *old = LogicPage;
|
||||
LogicPage = &ptr;
|
||||
return(old);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GBC::LOCK -- Locks a Direct Draw Surface *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/09/1995 : Created. *
|
||||
* 10/09/1995 : Code stolen from Steve Tall *
|
||||
*=========================================================================*/
|
||||
extern void Colour_Debug (int call_number);
|
||||
extern BOOL GameInFocus;
|
||||
|
||||
extern void Block_Mouse(GraphicBufferClass *buffer);
|
||||
extern void Unblock_Mouse(GraphicBufferClass *buffer);
|
||||
|
||||
BOOL GraphicBufferClass::Lock(void)
|
||||
{
|
||||
HRESULT result;
|
||||
int restore_attempts=0;
|
||||
|
||||
//
|
||||
// If its not a direct draw surface then the lock is always sucessful.
|
||||
//
|
||||
if (!IsDirectDraw) return(TRUE);
|
||||
|
||||
/*
|
||||
** If the video surface pointer is null then return
|
||||
*/
|
||||
if (!VideoSurfacePtr) return (FALSE);
|
||||
|
||||
/*
|
||||
** If we dont have focus then return failure
|
||||
*/
|
||||
if (!GameInFocus) return (FALSE);
|
||||
|
||||
|
||||
Block_Mouse(this);
|
||||
|
||||
|
||||
//
|
||||
// If surface is already locked then inc the lock count and return true
|
||||
//
|
||||
if (LockCount){
|
||||
LockCount++;
|
||||
Unblock_Mouse(this);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
//
|
||||
// If it isn't locked at all then we will have to request that Direct
|
||||
// Draw actually lock the surface.
|
||||
//
|
||||
|
||||
if (VideoSurfacePtr){
|
||||
while (!LockCount && restore_attempts<2) {
|
||||
result = VideoSurfacePtr->Lock ( NULL
|
||||
, &(VideoSurfaceDescription)
|
||||
, DDLOCK_WAIT
|
||||
, NULL);
|
||||
|
||||
switch (result){
|
||||
case DD_OK :
|
||||
Offset = (unsigned long)VideoSurfaceDescription.lpSurface;
|
||||
Pitch = VideoSurfaceDescription.lPitch;
|
||||
Pitch -= Width;
|
||||
LockCount++; // increment count so we can track if
|
||||
TotalLocks++; // Total number of times we have locked (for debugging)
|
||||
//Colour_Debug (1);
|
||||
Unblock_Mouse(this);
|
||||
return (TRUE); // we locked it multiple times.
|
||||
|
||||
case DDERR_SURFACELOST :
|
||||
if (Gbuffer_Focus_Loss_Function){
|
||||
Gbuffer_Focus_Loss_Function();
|
||||
}
|
||||
AllSurfaces.Restore_Surfaces();
|
||||
restore_attempts++;
|
||||
break;
|
||||
|
||||
default :
|
||||
Unblock_Mouse(this);
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Colour_Debug(1);
|
||||
Unblock_Mouse(this);
|
||||
return (FALSE); //Return false because we couldnt lock or restore the surface
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* GBC::UNLOCK -- Unlocks a direct draw surface *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/09/1995 : Created. *
|
||||
* 10/09/1995 : Code stolen from Steve Tall *
|
||||
*=========================================================================*/
|
||||
|
||||
|
||||
BOOL GraphicBufferClass::Unlock(void)
|
||||
{
|
||||
//
|
||||
// If there is no lock count or this is not a direct draw surface
|
||||
// then just return true as there is no harm done.
|
||||
//
|
||||
if (!(LockCount && IsDirectDraw)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
//
|
||||
// If lock count is directly equal to one then we actually need to
|
||||
// unlock so just give it a shot.
|
||||
//
|
||||
if (LockCount == 1 && VideoSurfacePtr) {
|
||||
Block_Mouse(this);
|
||||
if ( VideoSurfacePtr->Unlock ( NULL ) != DD_OK ){
|
||||
Unblock_Mouse(this);
|
||||
return(FALSE);
|
||||
} else {
|
||||
Offset=NOT_LOCKED;
|
||||
LockCount--;
|
||||
Unblock_Mouse(this);
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
//Colour_Debug (0);
|
||||
LockCount--;
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* GVPC::DD_Linear_Blit_To_Linear -- blit using the hardware blitter *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: destination vvpc *
|
||||
* x coord to blit from *
|
||||
* y coord to blit from *
|
||||
* x coord to blit to *
|
||||
* y coord to blit to *
|
||||
* width to blit *
|
||||
* height to blit *
|
||||
* *
|
||||
* OUTPUT: DD_OK if successful *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09-22-95 11:05am ST : Created *
|
||||
*=============================================================================================*/
|
||||
|
||||
HRESULT GraphicViewPortClass::DD_Linear_Blit_To_Linear (
|
||||
GraphicViewPortClass &dest
|
||||
, int source_x
|
||||
, int source_y
|
||||
, int dest_x
|
||||
, int dest_y
|
||||
, int width
|
||||
, int height
|
||||
, BOOL mask )
|
||||
|
||||
{
|
||||
RECT source_rectangle;
|
||||
RECT dest_rectangle;
|
||||
int key_source=0;
|
||||
|
||||
if ( mask ){
|
||||
key_source=DDBLT_KEYSRC;
|
||||
}
|
||||
|
||||
|
||||
source_rectangle.left = source_x;
|
||||
source_rectangle.top = source_y;
|
||||
source_rectangle.right = source_x+width;
|
||||
source_rectangle.bottom = source_y+height;
|
||||
|
||||
dest_rectangle.left = dest_x;
|
||||
dest_rectangle.top = dest_y;
|
||||
dest_rectangle.right = dest_x+width;
|
||||
dest_rectangle.bottom = dest_y+height;
|
||||
|
||||
return ( dest.GraphicBuff->Get_DD_Surface()->Blt ( &dest_rectangle,
|
||||
GraphicBuff->Get_DD_Surface(),
|
||||
&source_rectangle,
|
||||
key_source | DDBLT_WAIT | DDBLT_ASYNC,
|
||||
NULL ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
124
WIN32LIB/SRCDEBUG/GETCD.CPP
Normal file
124
WIN32LIB/SRCDEBUG/GETCD.CPP
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : WWLIB *
|
||||
* *
|
||||
* File Name : GETCD.CPP *
|
||||
* *
|
||||
* Programmer : STEVE WETHERILL BASED ON JOE BOSTIC CODE *
|
||||
* *
|
||||
* Start Date : 5/13/94 *
|
||||
* *
|
||||
* Last Update : June 4, 1994 [SW] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* GetCDClass::GetCDClass -- default constructor *
|
||||
* GetCDClass::~GetCDClass -- destructor *
|
||||
* GetCDClass::GetCDDrive -- returns the logical CD drive *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dos.h>
|
||||
|
||||
#include "wwstd.h"
|
||||
#include "playcd.h"
|
||||
#include "wwmem.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GetCDClass -- default constructor *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* none *
|
||||
* OUTPUT: *
|
||||
* none *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/26/1994 SW : Created. *
|
||||
* 12/4/95 ST : fixed for Win95 *
|
||||
*=========================================================================*/
|
||||
|
||||
GetCDClass::GetCDClass(VOID)
|
||||
{
|
||||
char path[]={"a:\\"};
|
||||
|
||||
CDCount = 0;
|
||||
CDIndex = 0;
|
||||
|
||||
/*
|
||||
** Set all CD drive placeholders to empty
|
||||
*/
|
||||
memset (CDDrives, NO_CD_DRIVE, MAX_CD_DRIVES);
|
||||
|
||||
|
||||
for (char i='c' ; i<='z' ; i++){
|
||||
path[0]=i;
|
||||
if (GetDriveType (path) == DRIVE_CDROM){
|
||||
CDDrives[CDCount++] = (int) (i-'a');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Catch the case when there are NO CD-ROM drives available
|
||||
*/
|
||||
if (CDCount == 0) {
|
||||
for (char i='a' ; i<='b' ; i++){
|
||||
path[0]=i;
|
||||
if (GetDriveType (path) == DRIVE_CDROM){
|
||||
CDDrives[CDCount++] = (int) (i-'a');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* GetCDClass -- destructor *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* none *
|
||||
* OUTPUT: *
|
||||
* none *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/26/1994 SW: Created. *
|
||||
* 12/4/95 ST: fixed for Win95 *
|
||||
*=========================================================================*/
|
||||
|
||||
GetCDClass::~GetCDClass(VOID)
|
||||
{
|
||||
// if(cdDrive_addrp.seg)
|
||||
// DPMI_real_free(cdDrive_addrp); // free up those conventional buffers
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
115
WIN32LIB/SRCDEBUG/GETCLIP.ASM
Normal file
115
WIN32LIB/SRCDEBUG/GETCLIP.ASM
Normal file
@@ -0,0 +1,115 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood 32 bit Library *
|
||||
;* *
|
||||
;* File Name : BITBLIT.ASM *
|
||||
;* *
|
||||
;* Programmer : Julio R. Jerez *
|
||||
;* *
|
||||
;* Start Date : Feb 6, 1995 *
|
||||
;* *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE "gbuffer.inc"
|
||||
|
||||
|
||||
; typedef struct {
|
||||
; int x0 , y0 ;
|
||||
; int x1 , y1 ;
|
||||
; } CLIP_WIN ;
|
||||
; Note for efficiency reasons x1 must be >= x0 and y1 >= y0
|
||||
; int get_clip ( CLIP_WIN * window , CLIP_WIN * sorce_rect ) ;
|
||||
|
||||
CODESEG
|
||||
|
||||
PROC get_clip C near
|
||||
USES eax , ebx
|
||||
|
||||
;*===================================================================
|
||||
;* define the arguements that our function takes.
|
||||
;*===================================================================
|
||||
ARG win : dword
|
||||
ARG rect : dword
|
||||
|
||||
|
||||
mov edi , [ rect ]
|
||||
mov esi , [ win ]
|
||||
xor eax , eax
|
||||
xor edx , edx
|
||||
|
||||
mov ecx , [ (RECTANGLE edi) . x0 ]
|
||||
mov ebx , [ (RECTANGLE edi) . x1 ]
|
||||
sub ecx , [ (RECTANGLE esi) . x0 ]
|
||||
sub ebx , [ (RECTANGLE esi) . x0 ]
|
||||
shld eax , ecx , 1
|
||||
shld edx , ebx , 1
|
||||
|
||||
; mov ebx , [ (RECTANGLE esi) . x1 ]
|
||||
; inc ebx
|
||||
; mov [ rect ] , ebx
|
||||
mov ecx , [ (RECTANGLE edi) . x0 ]
|
||||
mov ebx , [ (RECTANGLE edi) . x1 ]
|
||||
sub ecx , [ (RECTANGLE esi) . x1 ]
|
||||
sub ebx , [ (RECTANGLE esi) . x1 ]
|
||||
dec ecx
|
||||
dec ebx
|
||||
shld eax , ecx , 1
|
||||
shld edx , ebx , 1
|
||||
|
||||
mov ecx , [ (RECTANGLE edi) . y0 ]
|
||||
mov ebx , [ (RECTANGLE edi) . y1 ]
|
||||
sub ecx , [ (RECTANGLE esi) . y0 ]
|
||||
sub ebx , [ (RECTANGLE esi) . y0 ]
|
||||
shld eax , ecx , 1
|
||||
shld edx , ebx , 1
|
||||
|
||||
; mov ebx , [ (RECTANGLE esi) . y1 ]
|
||||
; inc ebx
|
||||
; mov [ rect ] , ebx
|
||||
mov ecx , [ (RECTANGLE edi) . y0 ]
|
||||
mov ebx , [ (RECTANGLE edi) . y1 ]
|
||||
sub ecx , [ (RECTANGLE esi) . y1 ]
|
||||
sub ebx , [ (RECTANGLE esi) . y1 ]
|
||||
dec ecx
|
||||
dec ebx
|
||||
shld eax , ecx , 1
|
||||
shld edx , ebx , 1
|
||||
|
||||
xor al , 5
|
||||
xor dl , 5
|
||||
mov ah , dl
|
||||
ret
|
||||
ENDP get_clip
|
||||
|
||||
|
||||
|
||||
END
|
||||
106
WIN32LIB/SRCDEBUG/GETPIX.ASM
Normal file
106
WIN32LIB/SRCDEBUG/GETPIX.ASM
Normal file
@@ -0,0 +1,106 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : GraphicViewPortClass *
|
||||
;* *
|
||||
;* File Name : GETPIXEL.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil Gorrow *
|
||||
;* *
|
||||
;* Start Date : June 7, 1994 *
|
||||
;* *
|
||||
;* Last Update : June 7, 1994 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* VVPC::Buffer_Get_Pixel -- get the colour of a pixel at given coords *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
INCLUDE ".\drawbuff.inc"
|
||||
INCLUDE ".\gbuffer.inc"
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* VVPC::GET_PIXEL -- Gets a pixel from the current view port *
|
||||
;* *
|
||||
;* INPUT: WORD the x pixel on the screen. *
|
||||
;* WORD the y pixel on the screen. *
|
||||
;* *
|
||||
;* OUTPUT: UBYTE the pixel at the specified location *
|
||||
;* *
|
||||
;* WARNING: If pixel is to be placed outside of the viewport then *
|
||||
;* this routine will abort. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/07/1994 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
PROC Buffer_Get_Pixel C near
|
||||
USES ebx,ecx,edx,edi
|
||||
|
||||
ARG this_object:DWORD ; this is a member function
|
||||
ARG x_pixel:DWORD ; x position of pixel to set
|
||||
ARG y_pixel:DWORD ; y position of pixel to set
|
||||
|
||||
;*===================================================================
|
||||
; Get the viewport information and put bytes per row in ecx
|
||||
;*===================================================================
|
||||
mov ebx,[this_object] ; get a pointer to viewport
|
||||
xor eax,eax
|
||||
mov edi,[(GraphicViewPort ebx).GVPOffset] ; get the correct offset
|
||||
mov ecx,[(GraphicViewPort ebx).GVPHeight] ; edx = height of viewport
|
||||
mov edx,[(GraphicViewPort ebx).GVPWidth] ; ecx = width of viewport
|
||||
|
||||
;*===================================================================
|
||||
; Verify that the X pixel offset if legal
|
||||
;*===================================================================
|
||||
mov eax,[x_pixel] ; find the x position
|
||||
cmp eax,edx ; is it out of bounds
|
||||
jae short ??exit ; if so then get out
|
||||
add edi,eax ; otherwise add in offset
|
||||
|
||||
;*===================================================================
|
||||
; Verify that the Y pixel offset if legal
|
||||
;*===================================================================
|
||||
mov eax,[y_pixel] ; get the y position
|
||||
cmp eax,ecx ; is it out of bounds
|
||||
jae ??exit ; if so then get out
|
||||
add edx,[(GraphicViewPort ebx).GVPXAdd] ; otherwise find bytes per row
|
||||
add edx,[(GraphicViewPort ebx).GVPPitch] ; otherwise find bytes per row
|
||||
mul edx ; offset = bytes per row * y
|
||||
add edi,eax ; add it into the offset
|
||||
|
||||
;*===================================================================
|
||||
; Write the pixel to the screen
|
||||
;*===================================================================
|
||||
xor eax,eax ; clear the word
|
||||
mov al,[edi] ; read in the pixel
|
||||
??exit:
|
||||
ret
|
||||
ENDP Buffer_Get_Pixel
|
||||
|
||||
END
|
||||
362
WIN32LIB/SRCDEBUG/GETSHAPE.CPP
Normal file
362
WIN32LIB/SRCDEBUG/GETSHAPE.CPP
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : GETSHAPE.CPP *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : April 5, 1992 *
|
||||
* *
|
||||
* Last Update : May 25, 1994 [BR] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Get_Shape_Size -- Fetch the size of the shape in memory. *
|
||||
* Get_Shape_Uncomp_Size -- gets shape's uncompressed size in bytes *
|
||||
* Get_Shape_Data -- retrieves a shape's special prefix data *
|
||||
* Extract_Shape_Count -- returns # of shapes in the given shape block *
|
||||
* Extract_Shape -- Gets pointer to shape in given shape block *
|
||||
* Get_Shape_Width -- gets shape width in pixels *
|
||||
* Get_Shape_Height -- gets shape height in pixels *
|
||||
* Set_Shape_Height -- modifies shape's height *
|
||||
* Restore_Shape_Height -- restores a shape to its original height *
|
||||
* Get_Shape_Original_Height -- gets shape's unmodified height *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/*
|
||||
********************************* Includes **********************************
|
||||
*/
|
||||
#include "wwstd.h"
|
||||
#include "shape.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get_Shape_Size -- Fetch the size of the shape in memory. *
|
||||
* *
|
||||
* The shape size returned includes both the shape header & its data. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to shape *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* shape's size in memory *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int cdecl Get_Shape_Size(VOID const *shape)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
|
||||
/*
|
||||
------------------------- Return if NULL pointer -------------------------
|
||||
*/
|
||||
if (!shape)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
-------------------------- Returns shape's size --------------------------
|
||||
*/
|
||||
return (shp->ShapeSize);
|
||||
|
||||
} /* end of Get_Shape_Size */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get_Shape_Uncomp_Size -- gets shape's uncompressed size in bytes *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to shape *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* shape's size in bytes when uncompressed *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int Get_Shape_Uncomp_Size(VOID const *shape)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
|
||||
return (shp->DataLength);
|
||||
|
||||
} /* end of Get_Shape_Uncomp_Size */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get_Shape_Data -- retrieves a shape's special prefix data *
|
||||
* *
|
||||
* MAKESHPS.EXE can store special data values along with a shape. These *
|
||||
* values are inserted in the shape table >before< the shape's header. *
|
||||
* So, this routine uses the 'data' parameter as a negative index from *
|
||||
* the given shape pointer. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to shape *
|
||||
* data index of WORD data value to get *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* data value *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* The shape pointer must be a pointer into a shape table created by *
|
||||
* MAKESHPS.EXE; it >cannot< be a pointer to shape returned by Make_Shape! *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
WORD cdecl Get_Shape_Data(VOID const *shape, WORD data)
|
||||
{
|
||||
WORD *word_ptr = (WORD *)shape;
|
||||
WORD retval;
|
||||
|
||||
retval = *(word_ptr - (data+1));
|
||||
|
||||
return (retval);
|
||||
|
||||
} /* end of Get_Shape_Data */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Extract_Shape_Count -- returns # of shapes in the given shape block *
|
||||
* *
|
||||
* The # of shapes in a shape block is the first WORD in the block, so *
|
||||
* this is the value returned. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* buffer pointer to shape block, created with MAKESHPS.EXE *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* # shapes in the block *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int cdecl Extract_Shape_Count(VOID const *buffer)
|
||||
{
|
||||
ShapeBlock_Type *block = (ShapeBlock_Type *)buffer;
|
||||
|
||||
return (block->NumShapes);
|
||||
|
||||
} /* end of Extract_Shape_Count */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Extract_Shape -- Gets pointer to shape in given shape block *
|
||||
* *
|
||||
* INPUT: *
|
||||
* buffer pointer to shape block, created with MAKESHPS.EXE *
|
||||
* shape index of shape to get *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* pointer to shape in the shape block *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
VOID * cdecl Extract_Shape(VOID const *buffer, int shape)
|
||||
{
|
||||
ShapeBlock_Type *block = (ShapeBlock_Type*) buffer;
|
||||
int numshapes; // Number of shapes
|
||||
long offset; // Offset of shape data, from start of block
|
||||
char *bytebuf = (char*) buffer;
|
||||
|
||||
/*
|
||||
----------------------- Return if invalid argument -----------------------
|
||||
*/
|
||||
if (!buffer || shape < 0 || shape >= block->NumShapes)
|
||||
return(NULL);
|
||||
|
||||
offset = block->Offsets[shape];
|
||||
|
||||
return(bytebuf + 2 + offset);
|
||||
|
||||
} /* end of Extract_Shape */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get_Shape_Width -- gets shape width in pixels *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to a shape *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* shape width in pixels *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int Get_Shape_Width(VOID const *shape)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
|
||||
return (shp->Width);
|
||||
|
||||
} /* end of Get_Shape_Width */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get_Shape_Height -- gets shape height in pixels *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to a shape *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* shape height in pixels *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int Get_Shape_Height(VOID const *shape)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
|
||||
return (shp->Height);
|
||||
|
||||
} /* end of Get_Shape_Height */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Set_Shape_Height -- modifies shape's height *
|
||||
* *
|
||||
* The new height must be shorter than the original height. This effect *
|
||||
* chops off the lower portion of the shape, like it's sinking into the *
|
||||
* ground. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to a shape *
|
||||
* newheight new shape height *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* old shape height *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int cdecl Set_Shape_Height(VOID const *shape, WORD newheight)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
WORD oldheight;
|
||||
|
||||
oldheight = shp->Height;
|
||||
shp->Height = newheight;
|
||||
|
||||
return(oldheight);
|
||||
|
||||
} /* end of Set_Shape_Height */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Restore_Shape_Height -- restores a shape to its original height *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to a shape *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* old shape height *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int cdecl Restore_Shape_Height(VOID *shape)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
WORD oldheight;
|
||||
|
||||
oldheight = shp->Height;
|
||||
shp->Height = shp->OriginalHeight;
|
||||
|
||||
return(oldheight);
|
||||
|
||||
} /* end of Restore_Shape_Height */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get_Shape_Original_Height -- gets shape's unmodified height *
|
||||
* *
|
||||
* INPUT: *
|
||||
* shape pointer to a shape *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* shape's unmodified height *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1992 JLB : Created. *
|
||||
* 08/19/1993 SKB : Split drawshp.asm into several modules. *
|
||||
* 05/25/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
int Get_Shape_Original_Height(VOID const *shape)
|
||||
{
|
||||
Shape_Type *shp = (Shape_Type *)shape;
|
||||
|
||||
return (shp->OriginalHeight);
|
||||
|
||||
} /* end of Get_Shape_Original_Height */
|
||||
|
||||
|
||||
/************************* end of getshape.cpp *****************************/
|
||||
|
||||
216
WIN32LIB/SRCDEBUG/HARDERR.ASM
Normal file
216
WIN32LIB/SRCDEBUG/HARDERR.ASM
Normal file
@@ -0,0 +1,216 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Hard/Critical Error Handler *
|
||||
;* *
|
||||
;* File Name : harderr.asm *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen. *
|
||||
;* *
|
||||
;* Start Date : July 18, 1994 *
|
||||
;* *
|
||||
;* Last Update : July 26, 1994 [SKB] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Install_Hard_Error_Handler -- Setup for handling critical errors *
|
||||
;* Remove_Hard_Erroror_Handler -- Remove the critical error handler stuff*
|
||||
;* Critical_Error_Handler -- Catch critical error interrupt. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
LOCALS ??
|
||||
|
||||
;INCLUDE "tntdos.inc"
|
||||
|
||||
|
||||
;//////////////////////////////////////////////////////////////////////////////////////
|
||||
;///////////////////////////////////// Equates ////////////////////////////////////////
|
||||
DOS_SYS_CALL EQU 21h ; to do TNT DOS-XNDR system calls.
|
||||
LOCK_PAGES EQU 5 ; Lock pages subfunction using DX_MEM_MGT
|
||||
UNLOCK_PAGES EQU 6 ; Unlock pages subfunction using DX_MEM_MGT
|
||||
CRITERR_INT_NUM EQU 24h
|
||||
|
||||
DISK_ERROR_BIT EQU 01000000000000000b ; bit 7 of dh.
|
||||
DISK_ERROR EQU 1 ; Value of Hard_Error_Occured if disk/floppy error.
|
||||
OTHER_ERROR EQU 2 ; Value of Hard_Error_Occured if other type of error.
|
||||
|
||||
;
|
||||
; Interrupt handler stack frame
|
||||
;
|
||||
_FLGS equ [DWORD PTR ebp+52] ; 386|DOS-Extender flags
|
||||
_GS equ [WORD PTR ebp+48] ; original GS
|
||||
_FS equ [WORD PTR ebp+44] ; original FS
|
||||
_DS equ [WORD PTR ebp+40] ; original DS
|
||||
_ES equ [WORD PTR ebp+36] ; original ES
|
||||
_SS equ [WORD PTR ebp+32] ; original SS
|
||||
_ESP equ [DWORD PTR ebp+28] ; original ESP
|
||||
_EFLAGS equ [DWORD PTR ebp+24] ; original EFLAGS
|
||||
_CS equ [DWORD PTR ebp+20] ; original CS
|
||||
_EIP equ [DWORD PTR ebp+16] ; original EIP
|
||||
_EBP equ [DWORD PTR ebp] ; original EBP
|
||||
|
||||
;
|
||||
; DOS critical error stack frame
|
||||
;
|
||||
_DOS_FLAGS equ [WORD PTR es:ebx+22] ; interrupt stack frame from real
|
||||
_DOS_CS equ [WORD PTR es:ebx+20] ; mode INT 21h
|
||||
_DOS_IP equ [WORD PTR es:ebx+18] ;
|
||||
_DOS_ES equ [WORD PTR es:ebx+16] ; regs at time INT 21h was issued
|
||||
_DOS_DS equ [WORD PTR es:ebx+14] ; in real mode
|
||||
_DOS_BP equ [WORD PTR es:ebx+12] ;
|
||||
_DOS_DI equ [WORD PTR es:ebx+10] ;
|
||||
_DOS_SI equ [WORD PTR es:ebx+8] ;
|
||||
_DOS_DX equ [WORD PTR es:ebx+6] ;
|
||||
_DOS_CX equ [WORD PTR es:ebx+4] ;
|
||||
_DOS_BX equ [WORD PTR es:ebx+2] ;
|
||||
_DOS_AX equ [WORD PTR es:ebx] ;
|
||||
|
||||
|
||||
;
|
||||
; Error codes put into Hard_Error_Code
|
||||
;
|
||||
DISK_WRITE_PROTECTED equ 00h
|
||||
UNKOWN_DEVICE equ 01h
|
||||
DRIVE_NOT_READY equ 02h
|
||||
UNKOWN_COMMAND equ 03h
|
||||
CRC_ERROR equ 04h
|
||||
WRONG_DATA_LENGTH equ 05h
|
||||
SEEK_ERROR equ 06h
|
||||
UNKOWN_DEVICE_TYPE equ 07h
|
||||
SECTOR_NOT_FOUND equ 08h
|
||||
OUT_OF_PAPER equ 09h
|
||||
WRITE_ERROR equ 0Ah
|
||||
READ_ERROR equ 0Bh
|
||||
GENERAL_ERROR equ 0Ch
|
||||
|
||||
;//////////////////////////////////////////////////////////////////////////////////////
|
||||
;/////////////////////////////////// Prototypes ///////////////////////////////////////
|
||||
|
||||
GLOBAL Install_Hard_Error_Handler :NEAR
|
||||
GLOBAL Remove_Hard_Error_Handler :NEAR
|
||||
|
||||
;//////////////////////////////////////////////////////////////////////////////////////
|
||||
;///////////////////////////////// Global/Local Data //////////////////////////////////
|
||||
|
||||
DATASEG
|
||||
|
||||
LABEL LockedDataStart BYTE
|
||||
Hard_Error_Occured DB 0 ; Hard disk error or other error.
|
||||
Hard_Error_Code DB 0 ; Error Code.
|
||||
LABEL LockedDataEnd BYTE
|
||||
|
||||
|
||||
OldRMI DD ? ; original real mode critical err vector
|
||||
OldPMIOffset DD ? ; original protected mode critical err vector
|
||||
OldPMISelector DD ? ; original PM crit error selector.
|
||||
|
||||
InitFlags DD 0 ; Flags to indicate what has been initialized.
|
||||
|
||||
; InitFlags that are set to have a fully functional interrupt.
|
||||
IF_SET_VECTORS equ 1 ; Vectors have been set.
|
||||
IF_LOCKED_PM_CODE equ 2 ; Locked PM code for DPMI.
|
||||
IF_LOCKED_PM_DATA equ 4 ; Locked PM data for DPMI.
|
||||
IF_FUNCTIONAL equ 8 ; crit error is in and functional.
|
||||
|
||||
|
||||
;//////////////////////////////////////////////////////////////////////////////////////
|
||||
;///////////////////////////////////// Code //////////////////////////////////////////
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* INSTALL_HARD_ERROR_HANDLER -- Setup for handling critical errors. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 07/26/1994 SKB : Created. *
|
||||
;*=========================================================================*
|
||||
PROC Install_Hard_Error_Handler C near
|
||||
USES eax,ebx,ecx,ds,es
|
||||
ret
|
||||
|
||||
ENDP Install_Hard_Error_Handler
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* REMOVE_HARD_ERROROR_HANDLER -- Remove the critical error handler stuff *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 07/26/1994 SKB : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC Remove_Hard_Error_Handler C near
|
||||
USES ebx,ecx,edx,ds,es
|
||||
;
|
||||
; Restore the original interrupt vectors and exit
|
||||
;
|
||||
|
||||
ret
|
||||
|
||||
ENDP Remove_Hard_Error_Handler
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* Critical_Error_Handler -- Catch critical error interrupt. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 07/26/1994 SKB : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
PROC Critical_Error_Handler NEAR
|
||||
|
||||
ENDP Critical_Error_Handler
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
END
|
||||
|
||||
609
WIN32LIB/SRCDEBUG/ICONCACH.CPP
Normal file
609
WIN32LIB/SRCDEBUG/ICONCACH.CPP
Normal file
@@ -0,0 +1,609 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Drawbuff - Westwood win95 library *
|
||||
* *
|
||||
* File Name : Iconcach.CPP *
|
||||
* *
|
||||
* Programmer : Steve Tall *
|
||||
* *
|
||||
* Start Date : November 8th, 1995 *
|
||||
* *
|
||||
* Last Update : November 13th, 1995 [ST] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Overview: This file cantains members of the IconCacheClass and associated non member *
|
||||
* functions. All functions are to do with caching individual icons from icon sets *
|
||||
* into video memory to improve the speed of subsequent drawing *
|
||||
* *
|
||||
* Functions: *
|
||||
* Cache_New_Icon -- Call the Cache_It member to cache a registered icon to video memory *
|
||||
* Invalidate_Cached_Icons -- Uncache all the icons *
|
||||
* Restore_Cached_Icons -- restore cached icons after a focus loss *
|
||||
* Register_Icon_Set -- register an icon set as cachable *
|
||||
* Get_Free_Cache_Slot -- find an empty cache slot *
|
||||
* IconCacheClass::IconCacheClass -- IconCacheClass constructor *
|
||||
* IconCacheClass::~IconCacheClass -- IconCacheClass destructor *
|
||||
* IconCacheClass::Restore -- restore the icons surface and recache it *
|
||||
* IconCacheClass::Cache_It -- cache an icon into video memory *
|
||||
* IconCacheClass::Uncache_It -- restore the video memory used by a cached icon *
|
||||
* IconCacheClass::Draw_It -- use the blitter to draw the cached icon *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include "ddraw.h"
|
||||
#include "misc.h"
|
||||
#include "iconcach.h"
|
||||
#include "gbuffer.h"
|
||||
|
||||
|
||||
static DDSURFACEDESC VideoSurfaceDescription;
|
||||
|
||||
IconCacheClass CachedIcons[MAX_CACHED_ICONS];
|
||||
|
||||
extern "C"{
|
||||
IconSetType IconSetList[MAX_ICON_SETS];
|
||||
short IconCacheLookup[MAX_LOOKUP_ENTRIES];
|
||||
}
|
||||
|
||||
int CachedIconsDrawn=0; //Counter of number of cache hits
|
||||
int UnCachedIconsDrawn=0; //Counter of number of cache misses
|
||||
BOOL CacheMemoryExhausted; //Flag set if we have run out of video RAM
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Optimise_Video_Memory_Cache -- optimises usage of video memory *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: TRUE if memory was freed up *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/95 12:47PM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BOOL Optimize_Video_Memory_Cache (void)
|
||||
{
|
||||
|
||||
if (CacheMemoryExhausted &&
|
||||
(UnCachedIconsDrawn+CachedIconsDrawn > 1000) &&
|
||||
UnCachedIconsDrawn > CachedIconsDrawn){
|
||||
|
||||
int cache_misses[MAX_CACHED_ICONS];
|
||||
int cache_hits[MAX_CACHED_ICONS];
|
||||
int total_cache_misses=0;
|
||||
int total_cache_hits=0;
|
||||
int counter;
|
||||
int i;
|
||||
int j;
|
||||
int temp;
|
||||
BOOL swapped;
|
||||
|
||||
/*
|
||||
** make list of icons that have failed to cache more than 5 times
|
||||
*/
|
||||
for (counter=0 ; counter<MAX_CACHED_ICONS ; counter++){
|
||||
|
||||
if (CachedIcons[counter].TimesFailed>5){
|
||||
cache_misses[total_cache_misses++] = counter;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Make list of icons that have been drawn less than 3 times
|
||||
*/
|
||||
for (counter=0 ; counter<MAX_CACHED_ICONS ; counter++){
|
||||
|
||||
if (CachedIcons[counter].TimesDrawn<3){
|
||||
cache_hits[total_cache_hits++] = counter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Sort drawn icons into order
|
||||
*/
|
||||
if (total_cache_hits > 1){
|
||||
for (i = 0 ; i<total_cache_hits ; i++){
|
||||
swapped=FALSE;
|
||||
for (j=0 ; j<total_cache_hits-1 ; j++){
|
||||
|
||||
if (CachedIcons[cache_hits[j]].TimesDrawn > CachedIcons[cache_hits[j+1]].TimesDrawn){
|
||||
temp=cache_hits[j];
|
||||
cache_hits[j]=cache_hits[j+1];
|
||||
cache_hits[j+1]=temp;
|
||||
swapped = TRUE;
|
||||
}
|
||||
}
|
||||
if (!swapped) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Uncache icons up to the number of failed icons
|
||||
*/
|
||||
|
||||
for (counter=0 ; counter<total_cache_misses && counter<total_cache_hits; counter++){
|
||||
CachedIcons[cache_hits[counter]].Uncache_It();
|
||||
}
|
||||
|
||||
CacheMemoryExhausted=FALSE;
|
||||
CachedIconsDrawn=0;
|
||||
UnCachedIconsDrawn=0;
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Cache_New_Icon -- cache a registered icon to video memory *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: icon_index -- index into registered icon table of icon to cache *
|
||||
* icon_ptr -- ptr to icon data *
|
||||
* *
|
||||
* OUTPUT: BOOL success *
|
||||
* *
|
||||
* WARNINGS: icon must already have been registered and assigned an index *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:36AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BOOL Cache_New_Icon (int icon_index, void *icon_ptr)
|
||||
{
|
||||
if (!CacheMemoryExhausted){
|
||||
return (CachedIcons[icon_index].Cache_It(icon_ptr));
|
||||
} else {
|
||||
CachedIcons[icon_index].TimesFailed++;
|
||||
if (Optimize_Video_Memory_Cache()){
|
||||
return (CachedIcons[icon_index].Cache_It(icon_ptr));
|
||||
} else {
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Invalidat_Cached_Icons -- used to release any icons that have been cached *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:37AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void Invalidate_Cached_Icons (void)
|
||||
{
|
||||
for (int i=0 ; i<MAX_CACHED_ICONS ; i++){
|
||||
CachedIcons[i].Uncache_It();
|
||||
}
|
||||
|
||||
memset (&IconCacheLookup[0] , -1 ,MAX_LOOKUP_ENTRIES*sizeof(IconCacheLookup[0]));
|
||||
|
||||
for (i=0 ; i<MAX_ICON_SETS ; i++){
|
||||
IconSetList[i].IconSetPtr=NULL;
|
||||
}
|
||||
|
||||
CacheMemoryExhausted=FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Restore_Cached_Icons -- re-cache icons into video memory after a loss of focus *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: Assumes that the pointers that were originally used to cache the icons *
|
||||
* are still valid. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:38AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void Restore_Cached_Icons (void)
|
||||
{
|
||||
for (int i=0 ; i<MAX_CACHED_ICONS ; i++){
|
||||
CachedIcons[i].Restore();
|
||||
}
|
||||
CacheMemoryExhausted=FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Register_Icon_Set -- used to register an icon set as cachable *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: icon_data - ptr to icon set *
|
||||
* pre_cache -- should we pre-cache the icon data? *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:39AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void Register_Icon_Set (void *icon_data , BOOL pre_cache)
|
||||
{
|
||||
|
||||
for (int i=0 ; i<MAX_ICON_SETS ; i++){
|
||||
if (!IconSetList[i].IconSetPtr){
|
||||
IconSetList[i].IconSetPtr = (IControl_Type*)icon_data;
|
||||
|
||||
if (i){
|
||||
IControl_Type *previous_set = IconSetList[i-1].IconSetPtr;
|
||||
IconSetList[i].IconListOffset = IconSetList[i-1].IconListOffset + ((int)previous_set->Count)*2;
|
||||
if (IconSetList[i].IconListOffset > MAX_LOOKUP_ENTRIES*2){
|
||||
IconSetList[i].IconSetPtr = NULL;
|
||||
}
|
||||
} else {
|
||||
IconSetList[i].IconListOffset = 0;
|
||||
}
|
||||
|
||||
if (pre_cache){
|
||||
for (i=0 ; i<256 ; i++){
|
||||
Is_Icon_Cached(icon_data,i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Get_Free_Cache_Slot -- find a free slot in which to cache an icon *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: int - icon index *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:40AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
int Get_Free_Cache_Slot (void)
|
||||
{
|
||||
for (int i=0 ; i<MAX_CACHED_ICONS ; i++){
|
||||
if (!CachedIcons[i].Get_Is_Cached()){
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ICC::IconCacheClass -- constructor for icon cache class *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:41AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
IconCacheClass::IconCacheClass (void)
|
||||
{
|
||||
IsCached =FALSE;
|
||||
SurfaceLost =FALSE;
|
||||
DrawFrequency =0;
|
||||
CacheSurface =NULL;
|
||||
IconSource =NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ICC::~IconCacheClass -- destructor for icon cache class *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:41AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
IconCacheClass::~IconCacheClass (void)
|
||||
{
|
||||
if (IsCached && CacheSurface){
|
||||
CacheSurface->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ICC::Restore -- Restores the icons video surface memory and reloads it based on the original*
|
||||
* icon pointer *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: Relies on the icons original pointer still being valie *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:43AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void IconCacheClass::Restore (void)
|
||||
{
|
||||
if (IsCached && CacheSurface){
|
||||
CacheSurface->Restore();
|
||||
if (IconSource){
|
||||
Cache_It(IconSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ICC::Cache_It -- allocate video memory and copy an icon to it *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: icon_ptr -- ptr to icon data *
|
||||
* *
|
||||
* OUTPUT: bool -- success? *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:44AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
BOOL IconCacheClass::Cache_It (void *icon_ptr)
|
||||
{
|
||||
DDSCAPS surface_capabilities;
|
||||
BOOL return_value;
|
||||
|
||||
/*
|
||||
** If we dont have a direct draw interface yet then just fail
|
||||
*/
|
||||
if (!DirectDrawObject) return(FALSE);
|
||||
|
||||
/*
|
||||
** Set up the description of the surface we want to create
|
||||
*/
|
||||
memset (&VideoSurfaceDescription , 0 , sizeof ( VideoSurfaceDescription ));
|
||||
|
||||
VideoSurfaceDescription.dwSize = sizeof( VideoSurfaceDescription );
|
||||
VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
VideoSurfaceDescription.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
|
||||
VideoSurfaceDescription.dwHeight = ICON_WIDTH;
|
||||
VideoSurfaceDescription.dwWidth = ICON_HEIGHT;
|
||||
|
||||
/*
|
||||
** If this cache object doesnt already have a surface then create one
|
||||
*/
|
||||
if (!CacheSurface){
|
||||
if (DD_OK!=DirectDrawObject->CreateSurface( &VideoSurfaceDescription , &CacheSurface , NULL)){
|
||||
CacheMemoryExhausted = TRUE;
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure the surface we created isnt really in system memory
|
||||
*/
|
||||
if (DD_OK != CacheSurface->GetCaps(&surface_capabilities)){
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if ((DDSCAPS_SYSTEMMEMORY & surface_capabilities.dwCaps) == DDSCAPS_SYSTEMMEMORY){
|
||||
CacheSurface->Release();
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return_value=FALSE;
|
||||
/*
|
||||
** Lock the surface so we can copy the icon to it
|
||||
*/
|
||||
if (DD_OK== CacheSurface->Lock ( NULL
|
||||
, &(VideoSurfaceDescription)
|
||||
, DDLOCK_WAIT
|
||||
, NULL)){
|
||||
/*
|
||||
** Copy the icon to the surface and flag that icon is cached
|
||||
*/
|
||||
Cache_Copy_Icon (icon_ptr , VideoSurfaceDescription.lpSurface , VideoSurfaceDescription.lPitch);
|
||||
IsCached=TRUE;
|
||||
SurfaceLost=FALSE;
|
||||
IconSource=icon_ptr;
|
||||
return_value=TRUE;
|
||||
}
|
||||
CacheSurface->Unlock(NULL);
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ICC::Uncache_It -- release the video memory used to cache an icon *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:48AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void IconCacheClass::Uncache_It(void)
|
||||
{
|
||||
|
||||
if (IsCached && CacheSurface){
|
||||
CacheSurface->Release();
|
||||
IsCached=FALSE;
|
||||
CacheSurface=NULL;
|
||||
IconSource=NULL;
|
||||
CacheMemoryExhausted=FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ICC::Draw_It -- use the blitter to draw a cached icon *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: surface to draw to *
|
||||
* x coord to draw to (relative to window) *
|
||||
* y coord to draw to (relative to window) *
|
||||
* window left coord *
|
||||
* window top coord *
|
||||
* window width *
|
||||
* window height *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/95 9:48AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
void IconCacheClass::Draw_It (LPDIRECTDRAWSURFACE dest_surface , int x_pixel, int y_pixel, int window_left , int window_top , int window_width , int window_height)
|
||||
{
|
||||
RECT source_rectangle;
|
||||
RECT dest_rectangle;
|
||||
int clip;
|
||||
HRESULT return_code;
|
||||
|
||||
/*
|
||||
** Set up the source and destination coordinates as required by direct draw
|
||||
*/
|
||||
source_rectangle.left = 0;
|
||||
source_rectangle.top = 0;
|
||||
source_rectangle.right = ICON_WIDTH;
|
||||
source_rectangle.bottom = ICON_HEIGHT;
|
||||
|
||||
dest_rectangle.left = window_left+x_pixel;
|
||||
dest_rectangle.top = window_top+y_pixel;
|
||||
dest_rectangle.right = dest_rectangle.left+ICON_WIDTH;
|
||||
dest_rectangle.bottom = dest_rectangle.top+ICON_HEIGHT;
|
||||
|
||||
/*
|
||||
** Clip the coordinates to the window
|
||||
*/
|
||||
if (dest_rectangle.left<window_left){
|
||||
source_rectangle.left += window_left-dest_rectangle.left;
|
||||
dest_rectangle.left=window_left;
|
||||
}
|
||||
|
||||
if (dest_rectangle.right>=window_left+window_width){
|
||||
clip = dest_rectangle.right-(window_left+window_width);
|
||||
source_rectangle.right -= clip;
|
||||
dest_rectangle.right -= clip;
|
||||
}
|
||||
|
||||
if (dest_rectangle.top<window_top){
|
||||
source_rectangle.top += window_top-dest_rectangle.top;
|
||||
dest_rectangle.top=window_top;
|
||||
}
|
||||
|
||||
if (dest_rectangle.bottom>=window_top+window_height){
|
||||
clip = dest_rectangle.bottom-(window_top+window_height);
|
||||
source_rectangle.bottom -= clip;
|
||||
dest_rectangle.bottom -= clip;
|
||||
}
|
||||
|
||||
if (source_rectangle.left>=source_rectangle.right){
|
||||
return;
|
||||
}
|
||||
|
||||
if (source_rectangle.top>=source_rectangle.bottom){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** Do the blit
|
||||
*/
|
||||
return_code = dest_surface->Blt (&dest_rectangle ,
|
||||
CacheSurface ,
|
||||
&source_rectangle ,
|
||||
DDBLT_WAIT |
|
||||
DDBLT_ASYNC ,
|
||||
NULL);
|
||||
|
||||
if (return_code == DDERR_SURFACELOST && Gbuffer_Focus_Loss_Function){
|
||||
Gbuffer_Focus_Loss_Function();
|
||||
}
|
||||
|
||||
if ( return_code != DDERR_SURFACELOST && return_code != DD_OK ) {
|
||||
char temp[100];
|
||||
sprintf(temp,"DD Error code %d\n", return_code & 0xFFFF);
|
||||
OutputDebugString(temp);
|
||||
}
|
||||
|
||||
TimesDrawn++;
|
||||
|
||||
}
|
||||
|
||||
342
WIN32LIB/SRCDEBUG/ICONSET.CPP
Normal file
342
WIN32LIB/SRCDEBUG/ICONSET.CPP
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Library *
|
||||
* *
|
||||
* File Name : ICONSET.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : June 9, 1991 *
|
||||
* *
|
||||
* Last Update : September 15, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Load_Icon_Set -- Loads an icons set and initializes it. *
|
||||
* Free_Icon_Set -- Frees allocations made by Load_Icon_Set(). *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//#include "function.h"
|
||||
|
||||
#define _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <dos.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <mem.h>
|
||||
#include <wwstd.h>
|
||||
#include <file.h>
|
||||
#include "tile.h"
|
||||
#include <iff.h>
|
||||
|
||||
|
||||
|
||||
extern int Misc;
|
||||
|
||||
void * Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize);
|
||||
void Free_Icon_Set(void const *iconset);
|
||||
long Get_Icon_Set_Size(void const *iconset);
|
||||
int Get_Icon_Set_Width(void const *iconset);
|
||||
int Get_Icon_Set_Height(void const *iconset);
|
||||
void * Get_Icon_Set_Icondata(void const *iconset);
|
||||
void * Get_Icon_Set_Trans(void const *iconset);
|
||||
void * Get_Icon_Set_Remapdata(void const *iconset);
|
||||
void * Get_Icon_Set_Palettedata(void const *iconset);
|
||||
int Get_Icon_Set_Count(void const *iconset);
|
||||
void * Get_Icon_Set_Map(void const *iconset);
|
||||
|
||||
|
||||
//#define ICON_PALETTE_BYTES 16
|
||||
//#define ICON_MAX 256
|
||||
|
||||
/***************************************************************************
|
||||
** The terrain is rendered by using icons. These are the buffers that hold
|
||||
** the icon data, remap tables, and remap index arrays.
|
||||
*/
|
||||
//PRIVATE char *IconPalette = NULL; // MCGA only.
|
||||
//PRIVATE char *IconRemap = NULL; // MCGA only.
|
||||
|
||||
#define FORM_RPAL MAKE_ID('R','P','A','L')
|
||||
#define FORM_RTBL MAKE_ID('R','T','B','L')
|
||||
#define FORM_SSET MAKE_ID('S','S','E','T')
|
||||
#define FORM_SINF MAKE_ID('S','I','N','F')
|
||||
#define FORM_ICON MAKE_ID('I','C','O','N')
|
||||
#define FORM_TRNS MAKE_ID('T','R','N','S')
|
||||
#define FORM_MAP MAKE_ID('M','A','P',' ')
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* LOAD_ICON_SET -- Loads an icons set and initializes it. *
|
||||
* *
|
||||
* This routine will load an IFF icon set from disk. It handles all *
|
||||
* of the necessary allocations. *
|
||||
* *
|
||||
* INPUT: filename -- Name of the icon file. *
|
||||
* *
|
||||
* buffer -- Pointer to paragraph aligned buffer to hold data. *
|
||||
* *
|
||||
* size -- Size of the buffer (in bytes). *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: In EEGA mode the iconset buffer will be free because the *
|
||||
* icons will have been transferred to card ram. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1991 JLB : Created. *
|
||||
* 07/01/1991 JLB : Determines icon size from file. *
|
||||
* 07/15/1991 JLB : Load and uncompress onto the same buffer. *
|
||||
* 09/15/1993 JLB : Added EMS support. *
|
||||
*=========================================================================*/
|
||||
void * Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize)
|
||||
{
|
||||
int fh; // File handle of iconset.
|
||||
int bytespericon; // The number of bytes per icon.
|
||||
unsigned long icons=0; // Number of icons loaded.
|
||||
unsigned long size; // Size of the icon chunk (raw).
|
||||
|
||||
unsigned long transsize;
|
||||
void *transptr=NULL;
|
||||
|
||||
unsigned long mapsize; // Icon map chunk size.
|
||||
void *mapptr=NULL; // Icon map pointer.
|
||||
void *returnptr=NULL; // Iconset pointer returned by routine.
|
||||
BOOL allocated=FALSE; // Was the iconset block allocated?
|
||||
IControl_Type *idata=NULL; // Icon data loaded.
|
||||
long id; // ID of file openned.
|
||||
struct {
|
||||
char Width; // Width of icon in bytes.
|
||||
char Height; // Height of icon in bytes.
|
||||
char Format; // Graphic mode.
|
||||
//lint -esym(754,Format)
|
||||
char Bitplanes; // Number of bitplanes per icon.
|
||||
} sinf;
|
||||
|
||||
/*
|
||||
** Open the icon set for loading. If it is not a legal icon set
|
||||
** data file, then abort.
|
||||
*/
|
||||
fh = Open_Iff_File(filename);
|
||||
if (fh != WW_ERROR) {
|
||||
Read_File(fh, &id, sizeof(long));
|
||||
if (id == FORM_ICON) {
|
||||
|
||||
/*
|
||||
** Determine the size of the icons and set up the graphic
|
||||
** system accordingly. Also get the sizes of the various
|
||||
** data blocks that have to be loaded.
|
||||
*/
|
||||
Read_Iff_Chunk(fh, FORM_SINF, &sinf, sizeof(sinf));
|
||||
bytespericon = ((((int)sinf.Width)<<3)*(((int)sinf.Height)<<3)*(int)sinf.Bitplanes)>>3;
|
||||
|
||||
size = Get_Iff_Chunk_Size(fh,FORM_SSET);
|
||||
transsize = Get_Iff_Chunk_Size(fh, FORM_TRNS);
|
||||
mapsize = Get_Iff_Chunk_Size(fh, FORM_MAP);
|
||||
|
||||
/*
|
||||
** Allocate the icon buffer if one isn't provided. First try EMS and
|
||||
** then try conventional RAM.
|
||||
*/
|
||||
allocated = FALSE;
|
||||
if (!iconsetptr) {
|
||||
buffsize = size + transsize + mapsize + sizeof(IControl_Type);
|
||||
|
||||
Misc = buffsize;
|
||||
iconsetptr = Alloc(buffsize, MEM_NORMAL);
|
||||
allocated = (iconsetptr != NULL);
|
||||
}
|
||||
|
||||
if (iconsetptr && (size+transsize+mapsize+sizeof(IControl_Type)) <= buffsize) {
|
||||
|
||||
idata = (IControl_Type *)iconsetptr;
|
||||
|
||||
memset(idata, 0, sizeof(IControl_Type));
|
||||
|
||||
/*
|
||||
** Initialize the iconset header structure.
|
||||
*/
|
||||
idata->Width = (short)(((short)sinf.Width)<<3);
|
||||
idata->Height = (short)(((short)sinf.Height)<<3);
|
||||
idata->Allocated = (short)allocated;
|
||||
idata->Icons = (long)iconsetptr + sizeof(IControl_Type);
|
||||
idata->Map = idata->Icons + size;
|
||||
idata->TransFlag = sizeof(IControl_Type) + size + mapsize;
|
||||
idata->Size = buffsize;
|
||||
|
||||
{
|
||||
long val;
|
||||
|
||||
val = Read_Iff_Chunk(fh, FORM_SSET, Add_Long_To_Pointer(iconsetptr, sizeof(IControl_Type)), size);
|
||||
icons = (int)(val/(long)bytespericon);
|
||||
idata = (IControl_Type *)iconsetptr;
|
||||
}
|
||||
|
||||
if (mapsize) {
|
||||
icons = mapsize;
|
||||
}
|
||||
idata->Count = (short)icons;
|
||||
|
||||
/*
|
||||
** Limit buffer to only the size needed. This is done AFTER loading of the
|
||||
** raw icon data because it might have been compressed and thus need any
|
||||
** extra space to perform an overlapped decompression.
|
||||
*/
|
||||
if (buffsize > size + transsize + mapsize + sizeof(IControl_Type)) {
|
||||
buffsize = size + transsize + mapsize + sizeof(IControl_Type);
|
||||
}
|
||||
|
||||
transptr = Add_Long_To_Pointer(iconsetptr, idata->TransFlag);
|
||||
Read_Iff_Chunk(fh, FORM_TRNS, transptr, transsize);
|
||||
idata = (IControl_Type *)iconsetptr;
|
||||
|
||||
mapptr = (void*)idata->Map;
|
||||
Read_Iff_Chunk(fh, FORM_MAP, mapptr, mapsize);
|
||||
|
||||
/*
|
||||
** Let the graphic overlay know of the icon data. This could involve
|
||||
** translation and other data manipulations.
|
||||
*/
|
||||
//Init_Stamps(iconsetptr);
|
||||
|
||||
returnptr = iconsetptr;
|
||||
}
|
||||
}
|
||||
Close_Iff_File(fh);
|
||||
}
|
||||
|
||||
return (returnptr); // Return with icon pointer.
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FREE_ICON_SET -- Frees allocations made by Load_Icon_Set(). *
|
||||
* *
|
||||
* This routine is used to free up any allocations by Load_Icon_Set(). *
|
||||
* Use this routine when a new icon set is to be loaded. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1991 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
void Free_Icon_Set(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol) {
|
||||
if (icontrol->Allocated) {
|
||||
Free((void *)iconset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long Get_Icon_Set_Size(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
long size=0;
|
||||
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol) {
|
||||
size = icontrol->Size;
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
int Get_Icon_Set_Width(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
int width=0;
|
||||
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol) {
|
||||
width = icontrol->Width;
|
||||
}
|
||||
return(width);
|
||||
}
|
||||
|
||||
|
||||
int Get_Icon_Set_Height(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
int height=0;
|
||||
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol) {
|
||||
height = icontrol->Height;
|
||||
}
|
||||
return(height);
|
||||
}
|
||||
|
||||
|
||||
void * Get_Icon_Set_Icondata(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol)
|
||||
return(Add_Long_To_Pointer(iconset, (LONG)icontrol->Icons));
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void * Get_Icon_Set_Trans(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
void *ptr=NULL;
|
||||
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol) {
|
||||
ptr = Add_Long_To_Pointer((void *)iconset, icontrol->TransFlag);
|
||||
}
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
int Get_Icon_Set_Count(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
int count;
|
||||
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol) {
|
||||
count = icontrol->Count;
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
||||
void * Get_Icon_Set_Map(void const *iconset)
|
||||
{
|
||||
IControl_Type *icontrol;
|
||||
icontrol = (IControl_Type *)iconset;
|
||||
if (icontrol)
|
||||
return(Add_Long_To_Pointer(iconset, (LONG)icontrol->Map));
|
||||
return(NULL);
|
||||
}
|
||||
328
WIN32LIB/SRCDEBUG/IFF.CPP
Normal file
328
WIN32LIB/SRCDEBUG/IFF.CPP
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : IFF.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : May 16, 1991 *
|
||||
* *
|
||||
* Last Update : April 19, 1994 [SKB] *
|
||||
* *
|
||||
* *
|
||||
* IFF reader code designed for loading pictures (ILBM or PBM). *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Close_Iff_File -- Closes an IFF file handle. *
|
||||
* Get_Iff_Chunk_Size -- Get the size of the given IFF chunk. *
|
||||
* Open_Iff_File -- Opens an IFF file for reading. *
|
||||
* Read_Iff_Chunk -- Reads a chunk from an IFF file. *
|
||||
* Write_Iff_Chunk -- Writes an IFF chuck out. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "iff.h"
|
||||
#include "file.h"
|
||||
|
||||
#define ID_FORM MAKE_ID('F','O','R','M')
|
||||
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* OPEN_IFF_FILE -- Opens an IFF file for reading. *
|
||||
* *
|
||||
* This function will open an IFF file for reading. It will perform *
|
||||
* a the simple validity test of checking the first four bytes to make *
|
||||
* sure they are "FORM". The value returned is the filehandle of the *
|
||||
* opened file. *
|
||||
* *
|
||||
* INPUT: filename - ASCII name of the IFF file to be opened. *
|
||||
* *
|
||||
* OUTPUT: Returns the filehandle. If there is an error or the file *
|
||||
* is not an IFF FORM then -1 will be returned. *
|
||||
* *
|
||||
* WARNINGS: You are responsible for error handling if this function *
|
||||
* returns -1 (not an IFF file). *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
int __cdecl Open_Iff_File(char const *filename)
|
||||
{
|
||||
int fh; // File handle.
|
||||
long type; // IFF file type.
|
||||
|
||||
|
||||
/* We want to be able to open the file for READ | WRITE, but we do not
|
||||
want the Open_File to create it. So check to see if it exists before
|
||||
the Open_File */
|
||||
|
||||
// fh = Open_File(filename, READ); // Open the source file for READ
|
||||
// Close_File(fh);
|
||||
|
||||
//fh = Open_File(filename, READ | WRITE); // Open the source file again
|
||||
fh = Open_File(filename, READ); // Open the source file again
|
||||
|
||||
// Validate that it is a FORM type.
|
||||
|
||||
Read_File(fh, &type, 4L);
|
||||
|
||||
if (type == ID_FORM) {
|
||||
|
||||
// The file is valid (so far). Position the read so that the actual
|
||||
// IFF file type code can be read.
|
||||
|
||||
Seek_File(fh, 4L, SEEK_CUR); // Skip the filesize bytes.
|
||||
|
||||
} else {
|
||||
|
||||
// This is NOT an IFF file. Close the source file and return with
|
||||
// the error code.
|
||||
Close_File(fh);
|
||||
fh = WW_ERROR;
|
||||
}
|
||||
return fh;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CLOSE_IFF_FILE -- Closes an IFF file handle. *
|
||||
* *
|
||||
* The routine will close the file that was opened with the *
|
||||
* Open_Iff_File() function. *
|
||||
* *
|
||||
* INPUT: fh - File handle that was returned from Open_Iff_File(). *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
void __cdecl Close_Iff_File(int fh)
|
||||
{
|
||||
if (fh != WW_ERROR) Close_File(fh);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GET_IFF_CHUNK_SIZE -- Get the size of the given IFF chunk. *
|
||||
* *
|
||||
* INPUT: int file handle to open IFF file, long id to get size of *
|
||||
* *
|
||||
* OUTPUT: long size of the chunk or 0L if it was not found *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/03/1991 CY : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Get_Iff_Chunk_Size(int fh, long id)
|
||||
{
|
||||
long form; // Chunk iff form name.
|
||||
long chunksize; // Size of the chunk.
|
||||
char first_iteration; // Check once the current chunk name
|
||||
|
||||
|
||||
first_iteration = TRUE;
|
||||
|
||||
for (;;) {
|
||||
if (Read_File(fh, &form, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
|
||||
if (Read_File(fh, (char *) &chunksize, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
#if(IBM)
|
||||
chunksize = Reverse_Long(chunksize);
|
||||
#endif
|
||||
|
||||
if (id == form) {
|
||||
Seek_File(fh, -8L, SEEK_CUR); // Seek back to the start of
|
||||
return(chunksize); // the chunk & return size
|
||||
} else {
|
||||
|
||||
if (first_iteration) {
|
||||
Seek_File(fh, 12L, SEEK_SET); // Start at beginning of file.
|
||||
first_iteration = FALSE; // Don't do this again
|
||||
} else {
|
||||
|
||||
/* Otherwise, go to the next chunk in the file */
|
||||
|
||||
chunksize = (chunksize + 1) & 0xFFFFFFFEL;
|
||||
Seek_File(fh, chunksize, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0L);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* READ_IFF_CHUNK -- Reads a chunk from an IFF file. *
|
||||
* *
|
||||
* Once an IFF file is opened, various chunks must be read from it. *
|
||||
* This routine will search through the IFF file and load in the *
|
||||
* specified chunk. It will scan through the entire file when *
|
||||
* searching for the chunk. It will load the FIRST chunk of the given *
|
||||
* type. *
|
||||
* *
|
||||
* INPUT: fh - File handle of IFF file. *
|
||||
* *
|
||||
* id - Chunk ID code. *
|
||||
* *
|
||||
* buffer - Pointer to buffer to load the chunk. *
|
||||
* *
|
||||
* maxsize - Maximum data bytes to read. *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes read from the chunk. *
|
||||
* If 0 is returned, this indicates that the chunk wasn't *
|
||||
* found. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Read_Iff_Chunk(int fh, long id, void *buffer, unsigned long maxsize)
|
||||
{
|
||||
long form; // Chunk iff form name.
|
||||
unsigned long chunksize; // Size of the chunk.
|
||||
char first_iteration; // Check once the current chunk name
|
||||
|
||||
first_iteration = TRUE;
|
||||
|
||||
for (;;) {
|
||||
if (Read_File(fh, &form, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
if (Read_File(fh, (char *) &chunksize, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
#if(IBM)
|
||||
chunksize = Reverse_Long(chunksize);
|
||||
#endif
|
||||
|
||||
if (id == form) {
|
||||
|
||||
maxsize = MIN(maxsize, chunksize);
|
||||
Read_File(fh, buffer, maxsize); // Read the buffer.
|
||||
|
||||
chunksize = (chunksize + 1) & 0xFFFFFFFEL;
|
||||
if (maxsize < chunksize) {
|
||||
Seek_File(fh, chunksize - maxsize, SEEK_CUR);
|
||||
}
|
||||
return(maxsize);
|
||||
} else {
|
||||
|
||||
if (first_iteration) {
|
||||
Seek_File(fh, 12L, SEEK_SET); // Start at beginning of file.
|
||||
first_iteration = FALSE; // Don't do this again
|
||||
|
||||
} else {
|
||||
|
||||
/* Otherwise, go to the next chunk in the file */
|
||||
|
||||
chunksize = (chunksize + 1) & 0xFFFFFFFEL;
|
||||
Seek_File(fh, chunksize, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* WRITE_IFF_CHUNK -- Writes an IFF chuck out. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void __cdecl Write_Iff_Chunk(int file, long id, void *buffer, long length)
|
||||
{
|
||||
long pos; // Current position in the IFF file.
|
||||
long oldpos; // Record of start of chunk offset.
|
||||
long endpos; // end of file offset before we write our data
|
||||
long value;
|
||||
BOOL odd; // Is length odd?
|
||||
char pad = 0; // Optional padding byte for even sized chunks.
|
||||
|
||||
/*
|
||||
** Get the current end of file (before we write more data to the file)
|
||||
*/
|
||||
pos = Seek_File (file, 0L, SEEK_CUR);
|
||||
endpos = Seek_File (file, 0L, SEEK_END);
|
||||
Seek_File (file, pos, SEEK_SET);
|
||||
|
||||
if (length) {
|
||||
value = id;
|
||||
odd = (short)length & 0x01;
|
||||
|
||||
Write_File(file, &value, 4L);
|
||||
oldpos = Seek_File(file, 0L, SEEK_CUR);
|
||||
Write_File(file, &value, 4L);
|
||||
Write_File(file, buffer, length);
|
||||
pos = Seek_File(file, 0L, SEEK_CUR);
|
||||
if (odd) {
|
||||
Write_File(file, &pad, 1L);
|
||||
}
|
||||
|
||||
/*
|
||||
** Update the chunk size long.
|
||||
*/
|
||||
Seek_File(file, oldpos, SEEK_SET);
|
||||
value = IFFize_LONG((pos - oldpos)-4);
|
||||
Write_File(file, &value, 4L);
|
||||
|
||||
/*
|
||||
** Update the file size LONG. if we are not just overwriting existing data
|
||||
*/
|
||||
// (MCC)
|
||||
if ( endpos < pos ) {
|
||||
Seek_File(file, 4L, SEEK_SET);
|
||||
value = IFFize_LONG((pos+odd) - 8);
|
||||
Write_File(file, &value, 4L);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return to end of file.
|
||||
*/
|
||||
Seek_File(file, 0L, SEEK_END);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
72
WIN32LIB/SRCDEBUG/INITDLAY.CPP
Normal file
72
WIN32LIB/SRCDEBUG/INITDLAY.CPP
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : LIBRARY *
|
||||
* *
|
||||
* File Name : INITDLAY.C *
|
||||
* *
|
||||
* Programmer : Barry Green *
|
||||
* *
|
||||
* Last Update : August 3, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Init_Delay -- I am not sure *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "wwstd.h"
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
|
||||
BOOL VertBlank;
|
||||
|
||||
/***************************************************************************
|
||||
* INIT_DELAY -- I am not sure *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/03/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
VOID Init_Delay(VOID)
|
||||
{
|
||||
WORD nz, nnz;
|
||||
|
||||
nz = nnz = 0;
|
||||
|
||||
CountDown.Set(15, TRUE); // set to 1/4 second and start it
|
||||
|
||||
do {
|
||||
if (Get_Vert_Blank())
|
||||
nnz++;
|
||||
else
|
||||
nz++;
|
||||
} while (CountDown.Time());
|
||||
|
||||
VertBlank = (nnz > nz);
|
||||
}
|
||||
75
WIN32LIB/SRCDEBUG/INITMONO.CPP
Normal file
75
WIN32LIB/SRCDEBUG/INITMONO.CPP
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Initialize mono *
|
||||
* *
|
||||
* File Name : INITMONO.CPP *
|
||||
* *
|
||||
* Programmer : Jeff Wilson *
|
||||
* *
|
||||
* Start Date : March 28, 1994 *
|
||||
* *
|
||||
* Last Update : September 8, 1994 [IML] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef WWSTD_H
|
||||
#include "wwstd.h"
|
||||
#endif
|
||||
|
||||
#ifndef MONO_H
|
||||
#include "mono.h"
|
||||
#endif
|
||||
|
||||
#ifndef DESCMGMT_H
|
||||
#include "descmgmt.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* INITIALIZE_MONO_SCREEN -- Initializes the Mono display data *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/21/1994 jaw: Created. *
|
||||
*========================================================================*/
|
||||
|
||||
int Initialize_Mono_Screen(void)
|
||||
{
|
||||
// get a valid selector to mono screen.
|
||||
// Map_Segment_To_Address(0x0b0000UL, 0x8000UL);
|
||||
|
||||
MonoScreen = 0xb0000 ;
|
||||
|
||||
return (int)0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
69
WIN32LIB/SRCDEBUG/IRANDOM.CPP
Normal file
69
WIN32LIB/SRCDEBUG/IRANDOM.CPP
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : LIBRARY *
|
||||
* *
|
||||
* File Name : IRANDOM.C *
|
||||
* *
|
||||
* Programmer : Barry W. Green *
|
||||
* *
|
||||
* Last Update : 10 Feb, 1995 [BWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* IRANDOM ----------------------------------------------------------
|
||||
|
||||
IRandom returns a random value between min and max inclusive.
|
||||
|
||||
INPUTS: int min and int max
|
||||
|
||||
RETURNS: int random number
|
||||
*/
|
||||
|
||||
int IRandom(int minval, int maxval)
|
||||
{
|
||||
int num,mask;
|
||||
|
||||
// Keep minval and maxval straight.
|
||||
if (minval > maxval) {
|
||||
minval ^= maxval;
|
||||
maxval ^= minval;
|
||||
minval ^= maxval;
|
||||
}
|
||||
|
||||
mask = Get_Random_Mask(maxval - minval);
|
||||
|
||||
while( (num = (rand() & mask) + minval) > maxval ) ;
|
||||
return(num);
|
||||
}
|
||||
|
||||
2568
WIN32LIB/SRCDEBUG/KEYBOARD.ASM
Normal file
2568
WIN32LIB/SRCDEBUG/KEYBOARD.ASM
Normal file
File diff suppressed because it is too large
Load Diff
533
WIN32LIB/SRCDEBUG/KEYBOARD.CPP
Normal file
533
WIN32LIB/SRCDEBUG/KEYBOARD.CPP
Normal file
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Keyboard Library *
|
||||
* *
|
||||
* File Name : KEYBOARD.CPP *
|
||||
* *
|
||||
* Programmer : Philip W. Gorrow *
|
||||
* *
|
||||
* Start Date : 10/16/95 *
|
||||
* *
|
||||
* Last Update : October 26, 1995 [] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* WWKeyboardClass::Put -- Logic to insert a key into the keybuffer] *
|
||||
* WWKeyboardClass::Get -- Logic to get a metakey from the buffer *
|
||||
* WWKeyboardClass::Check -- Checks to see if a key is in the buffer *
|
||||
* WWKeyboardClass::Put_Key_Message -- Translates and inserts wParam into Keyboard Buffer *
|
||||
* WWKeyboardClass::Buff_Get -- Lowlevel function to get a key from key buffer *
|
||||
* WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels *
|
||||
* WWKeyboardClass::Get_Mouse_Y -- returns the mouses current y position in pixels *
|
||||
* WWKeyboardClass::Get_Mouse_XY -- Returns the mouses x,y position via reference vars *
|
||||
* Check_Key -- compatability routine for old 32 bit library *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "timer.h"
|
||||
#include "mono.h"
|
||||
|
||||
void Message_Loop(void);
|
||||
|
||||
WWKeyboardClass *_Kbd;
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::WWKeyBoardClass -- Construction for Westwood Keyboard Class *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/16/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
WWKeyboardClass::WWKeyboardClass(void)
|
||||
{
|
||||
_Kbd = this;
|
||||
//
|
||||
// Initialize the keyboard remap table for our system (note it would be bad if someone
|
||||
// switched keyboard modes after this happened.
|
||||
//
|
||||
memset(VKRemap, 0, 256);
|
||||
memset(AsciiRemap, 0, 2048);
|
||||
for (short lp = 31; lp < 255; lp ++) {
|
||||
if (isprint(lp)) {
|
||||
int vk_key = VkKeyScan((unsigned char)lp);
|
||||
if (vk_key > 0 && vk_key < 2048) {
|
||||
AsciiRemap[vk_key] = (unsigned char)lp;
|
||||
VKRemap[lp] = (unsigned char)(vk_key & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Build a remap table of the different keys which are affected by the caps lock and
|
||||
// the num lock.
|
||||
//
|
||||
memset(ToggleKeys, 0, 256);
|
||||
for (lp = 0; lp < 255; lp++ ) {
|
||||
if (isalpha(lp) && isupper(lp)) {
|
||||
ToggleKeys[lp] = 1;
|
||||
}
|
||||
if (lp >= VK_NUMPAD0 && lp <= VK_DIVIDE) {
|
||||
ToggleKeys[lp] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Our buffer should start devoid of keys.
|
||||
//
|
||||
memset(Buffer, 0, 256);
|
||||
Head = 0;
|
||||
Tail = 0;
|
||||
|
||||
//
|
||||
// There should be no starting queued mouse events for us to have to worry
|
||||
// about.
|
||||
//
|
||||
MouseQX = 0;
|
||||
MouseQY = 0;
|
||||
MState = 0;
|
||||
Conditional = 0;
|
||||
CurrentCursor = NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Buff_Get -- Lowlevel function to get a key from key buffer *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: int - the key value that was pulled from buffer (includes bits) * *
|
||||
* *
|
||||
* WARNINGS: If the key was a mouse event MouseQX and MouseQY will be updated *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
int WWKeyboardClass::Buff_Get(void)
|
||||
{
|
||||
while (!Check()) {} // wait for key in buffer
|
||||
int temp = Buffer[Head]; // get key out of the buffer
|
||||
int newhead = Head; // save off head for manipulation
|
||||
if (Is_Mouse_Key(temp)) { // if key is a mouse then
|
||||
MouseQX = Buffer[(Head + 1) & 255]; // get the x and y pos
|
||||
MouseQY = Buffer[(Head + 2) & 255]; // from the buffer
|
||||
newhead += 3; // adjust head forward
|
||||
} else {
|
||||
newhead += 1; // adjust head forward
|
||||
}
|
||||
newhead &= 255;
|
||||
Head = newhead;
|
||||
return(temp);
|
||||
}
|
||||
|
||||
BOOL WWKeyboardClass::Is_Mouse_Key(int key)
|
||||
{
|
||||
key &= 0xFF;
|
||||
return (key == VK_LBUTTON || key == VK_MBUTTON || key == VK_RBUTTON);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Check -- Checks to see if a key is in the buffer *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/16/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL WWKeyboardClass::Check(void)
|
||||
{
|
||||
Message_Loop();
|
||||
unsigned short temp; // store temp holding spot for key
|
||||
if (Head == Tail) return(FALSE); // if no keys in buff then get out
|
||||
temp = Buffer[Head]; // get key out of the buffer
|
||||
return(temp); // send it back to main program
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Get -- Logic to get a metakey from the buffer *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: int - the meta key taken from the buffer. *
|
||||
* *
|
||||
* WARNINGS: This routine will not return until a keypress is received *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/16/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
int WWKeyboardClass::Get(void)
|
||||
{
|
||||
int temp,bits; // store temp holding spot for key
|
||||
|
||||
while (!Check()) {} // wait for key in buffer
|
||||
temp = Buff_Get(); // get key from the buffer
|
||||
|
||||
bits = temp & 0xFF00; // save of keyboard bits
|
||||
|
||||
if (!(bits & WWKEY_VK_BIT)) { // if its not a virtual key
|
||||
temp = AsciiRemap[temp&0x1FF] | bits; // convert to ascii equivalent
|
||||
}
|
||||
return(temp); // return the key that we pulled out
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Put -- Logic to insert a key into the keybuffer] *
|
||||
* *
|
||||
* INPUT: int - the key to insert into the buffer *
|
||||
* *
|
||||
* OUTPUT: bool - true if key is sucessfuly inserted. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/16/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL WWKeyboardClass::Put(int key)
|
||||
{
|
||||
int temp = (Tail + 1) & 255;
|
||||
if (temp != Head)
|
||||
{
|
||||
Buffer[Tail] = (short)key;
|
||||
|
||||
//
|
||||
// Critical Line
|
||||
//
|
||||
Tail = temp;
|
||||
return(TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Put_Key_Message -- Translates and inserts wParam into Keyboard Buffer *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/16/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
WWKeyboardClass::Put_Key_Message(UINT vk_key, BOOL release, BOOL dbl)
|
||||
{
|
||||
int bits = 0;
|
||||
//
|
||||
// Get the status of all of the different keyboard modifiers. Note, only pay attention
|
||||
// to numlock and caps lock if we are dealing with a key that is affected by them. Note
|
||||
// that we do not want to set the shift, ctrl and alt bits for Mouse keypresses as this
|
||||
// would be incompatible with the dos version.
|
||||
//
|
||||
if (vk_key != VK_LBUTTON && vk_key != VK_MBUTTON && vk_key != VK_RBUTTON) {
|
||||
int shift = (GetKeyState(VK_SHIFT) & 0xFF00) != 0;
|
||||
int ctrl = (GetKeyState(VK_CONTROL) & 0xFF00) != 0;
|
||||
int alt = (GetKeyState(VK_MENU) & 0xFF00) != 0;
|
||||
int caps = ((GetKeyState(VK_CAPITAL) & 0x00FF) != 0) && (ToggleKeys[vk_key] == 1);
|
||||
int nums = ((GetKeyState(VK_NUMLOCK) & 0x00FF) != 0) && (ToggleKeys[vk_key] == 2);
|
||||
|
||||
//
|
||||
// Set the proper bits for whatever the key we got is.
|
||||
//
|
||||
if (shift || caps || nums) {
|
||||
bits |= WWKEY_SHIFT_BIT;
|
||||
}
|
||||
if (ctrl) {
|
||||
bits |= WWKEY_CTRL_BIT;
|
||||
}
|
||||
if (alt) {
|
||||
bits |= WWKEY_ALT_BIT;
|
||||
}
|
||||
}
|
||||
if (!AsciiRemap[vk_key|bits]) {
|
||||
bits |= WWKEY_VK_BIT;
|
||||
}
|
||||
if (release) {
|
||||
bits |= WWKEY_RLS_BIT;
|
||||
}
|
||||
if (dbl) {
|
||||
bits |= WWKEY_DBL_BIT;
|
||||
}
|
||||
//
|
||||
// Finally use the put command to enter the key into the keyboard
|
||||
// system.
|
||||
//
|
||||
return(Put(vk_key|bits));
|
||||
}
|
||||
|
||||
void WWKeyboardClass::Clear(void)
|
||||
{
|
||||
Head = Tail;
|
||||
}
|
||||
|
||||
int WWKeyboardClass::To_ASCII(int key)
|
||||
{
|
||||
if ( key && WWKEY_RLS_BIT)
|
||||
return(KN_NONE);
|
||||
return(key);
|
||||
}
|
||||
|
||||
WWKeyboardClass::Down(int key)
|
||||
{
|
||||
return(GetAsyncKeyState(key&0xFF));
|
||||
}
|
||||
|
||||
VOID WWKeyboardClass::Split(int &key, int &shift, int &ctrl, int &alt, int &rls, int &dbl)
|
||||
{
|
||||
shift = (key & WWKEY_SHIFT_BIT) != 0;
|
||||
ctrl = (key & WWKEY_CTRL_BIT) != 0;
|
||||
alt = (key & WWKEY_ALT_BIT) != 0;
|
||||
rls = (key & WWKEY_RLS_BIT) != 0;
|
||||
dbl = (key & WWKEY_DBL_BIT) != 0;
|
||||
key = (key & 0xFF);
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
void __cdecl Stop_Execution (void);
|
||||
}
|
||||
|
||||
#pragma off(unreferenced)
|
||||
void WWKeyboardClass::Message_Handler(HWND , UINT message, UINT wParam, LONG lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
if ( wParam==VK_SCROLL ){
|
||||
Stop_Execution();
|
||||
} else {
|
||||
Put_Key_Message(wParam);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
Put_Key_Message(wParam, TRUE);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
Put_Key_Message(VK_LBUTTON);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
Put_Key_Message(VK_LBUTTON, TRUE);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
Put_Key_Message(VK_LBUTTON, TRUE, TRUE);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
Put_Key_Message(VK_MBUTTON);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_MBUTTONUP:
|
||||
Put_Key_Message(VK_MBUTTON, TRUE);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_MBUTTONDBLCLK:
|
||||
Put_Key_Message(VK_MBUTTON, TRUE, TRUE);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
Put_Key_Message(VK_RBUTTON);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
Put_Key_Message(VK_RBUTTON, TRUE);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_RBUTTONDBLCLK:
|
||||
Put_Key_Message(VK_RBUTTON, TRUE, TRUE);
|
||||
Put(LOWORD(lParam));
|
||||
Put(HIWORD(lParam));
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
if (CurrentCursor)
|
||||
SetCursor(CurrentCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#pragma on(unreferenced)
|
||||
|
||||
|
||||
|
||||
|
||||
void Message_Loop(void)
|
||||
{
|
||||
|
||||
MSG msg;
|
||||
|
||||
while (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )) {
|
||||
if( !GetMessage( &msg, NULL, 0, 0 ) ){
|
||||
return;
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CHECK_KEY -- compatability routine for old 32 bit library *
|
||||
* *
|
||||
* This routine checks to see if there is a key in the keyboard buffer *
|
||||
* and returns it to the sender if there is. It does not remove the key *
|
||||
* from the buffer. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: The key that was pressed. *
|
||||
* *
|
||||
* WARNINGS: You must declare a WWKeyboardClass object before calling *
|
||||
* this routine. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/26/1995 : Created. *
|
||||
*=========================================================================*/
|
||||
int Check_Key(void)
|
||||
{
|
||||
if (!_Kbd) return(KA_NONE);
|
||||
return(_Kbd->Check() & ~WWKEY_SHIFT_BIT);
|
||||
}
|
||||
|
||||
void Clear_KeyBuffer(void)
|
||||
{
|
||||
if (!_Kbd) return;
|
||||
_Kbd->Clear();
|
||||
}
|
||||
|
||||
int Check_Key_Num(void)
|
||||
{
|
||||
if (!_Kbd) return(KN_NONE);
|
||||
int key = _Kbd->Check();
|
||||
int flags = key & 0xFF00;
|
||||
key = key & 0x00FF;
|
||||
|
||||
if (isupper(key)) {
|
||||
key = tolower(key);
|
||||
if ( !flags & WWKEY_VK_BIT ) {
|
||||
flags |= WWKEY_SHIFT_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
return(key | flags);
|
||||
}
|
||||
|
||||
int Get_Key_Num(void)
|
||||
{
|
||||
if (!_Kbd) return(KN_NONE);
|
||||
int key = _Kbd->Get();
|
||||
int flags = key & 0xFF00;
|
||||
key = key & 0x00FF;
|
||||
|
||||
if (isupper(key)) {
|
||||
key = tolower(key);
|
||||
if ( !flags & WWKEY_VK_BIT ) {
|
||||
flags |= WWKEY_SHIFT_BIT;
|
||||
}
|
||||
}
|
||||
return(key | flags);
|
||||
}
|
||||
|
||||
int KN_To_KA(int key)
|
||||
{
|
||||
if ( key & WWKEY_RLS_BIT) {
|
||||
return(KA_NONE);
|
||||
}
|
||||
if (!(key & WWKEY_VK_BIT)) {
|
||||
int flags = key & 0xFF00;
|
||||
key = key & 0x00FF;
|
||||
if (flags & WWKEY_SHIFT_BIT) {
|
||||
key = toupper(key);
|
||||
flags &= ~WWKEY_SHIFT_BIT;
|
||||
}
|
||||
}else{
|
||||
/*
|
||||
** If its a numeric keypad key then fix it up
|
||||
*/
|
||||
if ((key & 0xff) >=VK_NUMPAD0 && (key & 0xff) <=VK_NUMPAD9){
|
||||
key = (key & 0xff) - VK_NUMPAD0 + KA_0;
|
||||
}
|
||||
}
|
||||
return(key);
|
||||
}
|
||||
|
||||
int KN_To_VK(int key)
|
||||
{
|
||||
if (!_Kbd) return(KN_NONE);
|
||||
if ( key & WWKEY_RLS_BIT) {
|
||||
return(VK_NONE);
|
||||
}
|
||||
|
||||
int flags = key & 0xFF00;
|
||||
if (!(flags & WWKEY_VK_BIT)) {
|
||||
key = _Kbd->VKRemap[key & 0x00FF] | flags;
|
||||
}
|
||||
key &= ~WWKEY_VK_BIT;
|
||||
return(key);
|
||||
}
|
||||
|
||||
int Key_Down(int key)
|
||||
{
|
||||
if (!_Kbd) return(FALSE);
|
||||
return(_Kbd->Down(key));
|
||||
}
|
||||
|
||||
int Get_Key(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!_Kbd) return(KN_NONE);
|
||||
retval = _Kbd->Get() & ~WWKEY_SHIFT_BIT;
|
||||
if (retval & WWKEY_RLS_BIT) {
|
||||
retval = KN_NONE;
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
|
||||
1032
WIN32LIB/SRCDEBUG/KEYIPROT.ASM
Normal file
1032
WIN32LIB/SRCDEBUG/KEYIPROT.ASM
Normal file
File diff suppressed because it is too large
Load Diff
2638
WIN32LIB/SRCDEBUG/KEYIREAL.ASM
Normal file
2638
WIN32LIB/SRCDEBUG/KEYIREAL.ASM
Normal file
File diff suppressed because it is too large
Load Diff
286
WIN32LIB/SRCDEBUG/LCWCOMP.ASM
Normal file
286
WIN32LIB/SRCDEBUG/LCWCOMP.ASM
Normal file
@@ -0,0 +1,286 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/misc/rcs/lcwcomp.asm 1.1 1994/04/11 15:31:10 jeff_wilson Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Library routine *
|
||||
;* *
|
||||
;* File Name : COMPRESS.ASM *
|
||||
;* *
|
||||
;* Programmer : Louis Castle *
|
||||
;* *
|
||||
;* Last Update : 20 August, 1990 [CY] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* *
|
||||
; ULONG LCW_Compress(BYTE *source,BYTE *dest, ULONG length); *
|
||||
;* *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL LCW_Compress :NEAR
|
||||
|
||||
CODESEG
|
||||
|
||||
; ----------------------------------------------------------------
|
||||
;
|
||||
; Here are prototypes for the routines defined within this module:
|
||||
;
|
||||
; ULONG LCW_Compress(BYTE *source,BYTE *dest, ULONG length);
|
||||
;
|
||||
; ----------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
;***********************************************************
|
||||
;
|
||||
; ULONG LCW_Compress(BYTE *source, BYTE *dest, ULONG length)
|
||||
;
|
||||
; returns the size of the compressed data in bytes
|
||||
;
|
||||
;*
|
||||
PROC LCW_Compress C near
|
||||
USES ebx,ecx,edx,edi,esi
|
||||
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG datasize:DWORD
|
||||
|
||||
LOCAL inlen:DWORD
|
||||
LOCAL a1stdest:DWORD
|
||||
LOCAL a1stsrc:DWORD
|
||||
LOCAL lenoff:DWORD
|
||||
LOCAL ndest:DWORD
|
||||
LOCAL count:DWORD
|
||||
LOCAL matchoff:DWORD
|
||||
LOCAL end_of_data:DWORD
|
||||
|
||||
|
||||
cld
|
||||
mov edi,[dest]
|
||||
mov esi,[source]
|
||||
mov edx,[datasize] ; get length of data to compress
|
||||
|
||||
; mov ax,ds
|
||||
; mov es,ax
|
||||
|
||||
;
|
||||
; compress data to the following codes in the format b = byte, w = word
|
||||
; n = byte code pulled from compressed data
|
||||
; Bit field of n command description
|
||||
; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3
|
||||
; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes
|
||||
; n=11xxxxxx,w1 med run run x+3 bytes from offset w1
|
||||
; n=11111111,w1,w2 long run run w1 bytes from offset w2
|
||||
; n=10000000 end end of data reached
|
||||
;
|
||||
cld ; make sure all string commands are forward
|
||||
mov ebx,esi
|
||||
add ebx,edx
|
||||
mov [end_of_data],ebx
|
||||
mov [inlen],1 ; set the in-length flag
|
||||
mov [a1stdest],edi ; save original dest offset for size calc
|
||||
mov [a1stsrc],esi ; save offset of first byte of data
|
||||
mov [lenoff],edi ; save the offset of the legth of this len
|
||||
sub eax,eax
|
||||
mov al,081h ; the first byte is always a len
|
||||
stosb ; write out a len of 1
|
||||
lodsb ; get the byte
|
||||
stosb ; save it
|
||||
??loop:
|
||||
mov [ndest],edi ; save offset of compressed data
|
||||
mov edi,[a1stsrc] ; get the offset to the first byte of data
|
||||
mov [count],1 ; set the count of run to 0
|
||||
??searchloop:
|
||||
sub eax,eax
|
||||
mov al,[esi] ; get the current byte of data
|
||||
cmp al,[esi+64]
|
||||
jne short ??notrunlength
|
||||
|
||||
mov ebx,edi
|
||||
|
||||
mov edi,esi
|
||||
mov ecx,[end_of_data]
|
||||
sub ecx,edi
|
||||
repe scasb
|
||||
dec edi
|
||||
mov ecx,edi
|
||||
sub ecx,esi
|
||||
cmp ecx,65
|
||||
jb short ??notlongenough
|
||||
|
||||
mov [DWORD PTR inlen],0 ; clear the in-length flag
|
||||
mov esi,edi
|
||||
mov edi,[ndest] ; get the offset of our compressed data
|
||||
|
||||
mov ah,al
|
||||
mov al,0FEh
|
||||
stosb
|
||||
xchg ecx,eax
|
||||
stosw
|
||||
mov al,ch
|
||||
stosb
|
||||
|
||||
mov [ndest],edi ; save offset of compressed data
|
||||
mov edi,ebx
|
||||
jmp ??searchloop
|
||||
??notlongenough:
|
||||
mov edi,ebx
|
||||
??notrunlength:
|
||||
|
||||
??oploop:
|
||||
mov ecx,esi ; get the address of the last byte +1
|
||||
sub ecx,edi ; get the total number of bytes left to comp
|
||||
jz short ??searchdone
|
||||
|
||||
repne scasb ; look for a match
|
||||
jne short ??searchdone ; if we don't find one we're done
|
||||
|
||||
mov ebx,[count]
|
||||
mov ah,[esi+ebx-1]
|
||||
cmp ah,[edi+ebx-2]
|
||||
|
||||
jne ??oploop
|
||||
|
||||
mov edx,esi ; save this spot for the next search
|
||||
mov ebx,edi ; save this spot for the length calc
|
||||
dec edi ; back up one for compare
|
||||
mov ecx,[end_of_data] ; get the end of data
|
||||
sub ecx,esi ; sub current source for max len
|
||||
|
||||
repe cmpsb ; see how many bytes match
|
||||
|
||||
; start of change MH 9-24-91
|
||||
jne short ??notend ; if found mismatch then di - bx = match count
|
||||
|
||||
inc edi ; else cx = 0 and di + 1 - bx = match count
|
||||
|
||||
??notend:
|
||||
; end of change MH 9-24-91
|
||||
|
||||
mov esi,edx ; restore si
|
||||
mov eax,edi ; get the dest
|
||||
sub eax,ebx ; sub the start for total bytes that match
|
||||
mov edi,ebx ; restore dest
|
||||
cmp eax,[count] ; see if its better than before
|
||||
jb ??searchloop ; if not keep looking
|
||||
|
||||
mov [count],eax ; if so keep the count
|
||||
dec ebx ; back it up for the actual match offset
|
||||
mov [matchoff],ebx ; save the offset for later
|
||||
jmp ??searchloop ; loop until we searched it all
|
||||
|
||||
??searchdone:
|
||||
|
||||
mov ecx,[count] ; get the count of the longest run
|
||||
mov edi,[ndest] ; get the offset of our compressed data
|
||||
cmp ecx,2 ; see if its not enough run to matter
|
||||
jbe short ??lenin ; if its 0,1, or 2 its too small
|
||||
|
||||
cmp ecx,10 ; if not, see if it would fit in a short
|
||||
ja short ??medrun ; if not, see if its a medium run
|
||||
|
||||
mov eax,esi ; if its short get the current address
|
||||
sub eax,[matchoff] ; sub the offset of the match
|
||||
cmp eax,0FFFh ; if its less than 12 bits its a short
|
||||
ja short ??medrun ; if its not, its a medium
|
||||
|
||||
??shortrun:
|
||||
sub ebx,ebx
|
||||
mov bl,cl ; get the length (3-10)
|
||||
sub bl,3 ; sub 3 for a 3 bit number 0-7
|
||||
shl bl,4 ; shift it left 4
|
||||
add ah,bl ; add in the length for the high nibble
|
||||
xchg ah,al ; reverse the bytes for a word store
|
||||
jmp short ??srunnxt ; do the run fixup code
|
||||
|
||||
??medrun:
|
||||
cmp ecx,64 ; see if its a short run
|
||||
ja short ??longrun ; if not, oh well at least its long
|
||||
|
||||
sub cl,3 ; back down 3 to keep it in 6 bits
|
||||
or cl,0C0h ; the highest bits are always on
|
||||
mov al,cl ; put it in al for the stosb
|
||||
stosb ; store it
|
||||
jmp short ??medrunnxt ; do the run fixup code
|
||||
|
||||
??lenin:
|
||||
cmp [DWORD PTR inlen],0 ; is it doing a length?
|
||||
jnz short ??len ; if so, skip code
|
||||
|
||||
??lenin1:
|
||||
mov [lenoff],edi ; save the length code offset
|
||||
mov al,80h ; set the length to 0
|
||||
stosb ; save it
|
||||
|
||||
??len:
|
||||
mov ebx,[lenoff] ; get the offset of the length code
|
||||
cmp [BYTE PTR ebx],0BFh ; see if its maxed out
|
||||
je ??lenin1 ; if so put out a new len code
|
||||
|
||||
??stolen:
|
||||
inc [BYTE PTR ebx] ; inc the count code
|
||||
lodsb ; get the byte
|
||||
stosb ; store it
|
||||
mov [DWORD PTR inlen],1 ; we are now in a length so save it
|
||||
jmp short ??nxt ; do the next code
|
||||
|
||||
??longrun:
|
||||
mov al,0ffh ; its a long so set a code of FF
|
||||
stosb ; store it
|
||||
|
||||
mov eax,[count] ; send out the count
|
||||
stosw ; store it
|
||||
??medrunnxt:
|
||||
mov eax,[matchoff] ; get the offset
|
||||
sub eax,[a1stsrc] ; make it relative tot he start of data
|
||||
??srunnxt:
|
||||
stosw ; store it
|
||||
; this code common to all runs
|
||||
add esi,[count] ; add in the length of the run to the source
|
||||
mov [DWORD PTR inlen],0 ; set the in leght flag to false
|
||||
|
||||
;=======================================================================
|
||||
|
||||
??nxt:
|
||||
cmp esi,[end_of_data] ; see if we did the whole pic
|
||||
jae short ??out ; if so, cool! were done
|
||||
|
||||
jmp ??loop
|
||||
|
||||
??out:
|
||||
mov ax,080h ; remember to send an end of data code
|
||||
stosb ; store it
|
||||
mov eax,edi ; get the last compressed address
|
||||
sub eax,[a1stdest] ; sub the first for the compressed size
|
||||
|
||||
|
||||
ret
|
||||
|
||||
ENDP LCW_Compress
|
||||
|
||||
|
||||
END
|
||||
|
||||
292
WIN32LIB/SRCDEBUG/LCWUNCMP.ASM
Normal file
292
WIN32LIB/SRCDEBUG/LCWUNCMP.ASM
Normal file
@@ -0,0 +1,292 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/misc/rcs/lcwuncmp.asm 1.1 1994/04/11 15:31:21 jeff_wilson Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Library routine *
|
||||
;* *
|
||||
;* File Name : UNCOMP.ASM *
|
||||
;* *
|
||||
;* Programmer : Christopher Yates *
|
||||
;* *
|
||||
;* Last Update : 20 August, 1990 [CY] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* *
|
||||
; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); *
|
||||
;* *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C LCW_Uncompress :NEAR
|
||||
|
||||
CODESEG
|
||||
|
||||
; ----------------------------------------------------------------
|
||||
;
|
||||
; Here are prototypes for the routines defined within this module:
|
||||
;
|
||||
; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length);
|
||||
;
|
||||
; ----------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
PROC LCW_Uncompress C near
|
||||
|
||||
USES ebx,ecx,edx,edi,esi
|
||||
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG length:DWORD
|
||||
;LOCALS
|
||||
LOCAL a1stdest:DWORD
|
||||
LOCAL maxlen:DWORD
|
||||
LOCAL lastbyte:DWORD
|
||||
LOCAL lastcom:DWORD
|
||||
LOCAL lastcom1:DWORD
|
||||
|
||||
|
||||
mov edi,[dest]
|
||||
mov esi,[source]
|
||||
mov edx,[length]
|
||||
|
||||
;
|
||||
;
|
||||
; uncompress data to the following codes in the format b = byte, w = word
|
||||
; n = byte code pulled from compressed data
|
||||
; Bit field of n command description
|
||||
; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3
|
||||
; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes
|
||||
; n=11xxxxxx,w1 med run run x+3 bytes from offset w1
|
||||
; n=11111111,w1,w2 long copy copy w1 bytes from offset w2
|
||||
; n=11111110,w1,b1 long run run byte b1 for w1 bytes
|
||||
; n=10000000 end end of data reached
|
||||
;
|
||||
|
||||
mov [a1stdest],edi
|
||||
add edx,edi
|
||||
mov [lastbyte],edx
|
||||
cld ; make sure all lod and sto are forward
|
||||
mov ebx,esi ; save the source offset
|
||||
|
||||
??loop:
|
||||
mov eax,[lastbyte]
|
||||
sub eax,edi ; get the remaining byte to uncomp
|
||||
jz short ??out ; were done
|
||||
|
||||
mov [maxlen],eax ; save for string commands
|
||||
mov esi,ebx ; mov in the source index
|
||||
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
inc esi
|
||||
test al,al ; see if its a short run
|
||||
js short ??notshort
|
||||
|
||||
mov ecx,eax ;put count nibble in cl
|
||||
|
||||
mov ah,al ; put rel offset high nibble in ah
|
||||
and ah,0Fh ; only 4 bits count
|
||||
|
||||
shr cl,4 ; get run -3
|
||||
add ecx,3 ; get actual run length
|
||||
|
||||
cmp ecx,[maxlen] ; is it too big to fit?
|
||||
jbe short ??rsok ; if not, its ok
|
||||
|
||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
||||
|
||||
??rsok:
|
||||
mov al,[esi] ; get rel offset low byte
|
||||
lea ebx,[esi+1] ; save the source offset
|
||||
mov esi,edi ; get the current dest
|
||||
sub esi,eax ; get relative offset
|
||||
|
||||
rep movsb
|
||||
|
||||
jmp ??loop
|
||||
|
||||
??notshort:
|
||||
test al,40h ; is it a length?
|
||||
jne short ??notlength ; if not it could be med or long run
|
||||
|
||||
cmp al,80h ; is it the end?
|
||||
je short ??out ; if so its over
|
||||
|
||||
mov cl,al ; put the byte in count register
|
||||
and ecx,3Fh ; and off the extra bits
|
||||
|
||||
cmp ecx,[maxlen] ; is it too big to fit?
|
||||
jbe short ??lenok ; if not, its ok
|
||||
|
||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
||||
|
||||
??lenok:
|
||||
rep movsb
|
||||
|
||||
mov ebx,esi ; save the source offset
|
||||
jmp ??loop
|
||||
|
||||
??out:
|
||||
mov eax,edi
|
||||
sub eax,[a1stdest]
|
||||
jmp ??exit
|
||||
|
||||
??notlength:
|
||||
mov cl,al ; get the entire code
|
||||
and ecx,3Fh ; and off all but the size -3
|
||||
add ecx,3 ; add 3 for byte count
|
||||
|
||||
cmp al,0FEh
|
||||
jne short ??notrunlength
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[esi]
|
||||
|
||||
xor eax,eax
|
||||
mov al,[esi+2]
|
||||
lea ebx,[esi+3] ;save the source offset
|
||||
|
||||
cmp ecx,[maxlen] ; is it too big to fit?
|
||||
jbe short ??runlenok ; if not, its ok
|
||||
|
||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
||||
|
||||
??runlenok:
|
||||
test ecx,0ffe0h
|
||||
jnz ??dont_use_stosb
|
||||
rep stosb
|
||||
jmp ??loop
|
||||
|
||||
|
||||
??dont_use_stosb:
|
||||
mov ah,al
|
||||
mov edx,eax
|
||||
shl eax,16
|
||||
or eax,edx
|
||||
|
||||
test edi,3
|
||||
jz ??aligned
|
||||
|
||||
mov [edi],eax
|
||||
mov edx,edi
|
||||
and edi,0fffffffch
|
||||
lea edi,[edi+4]
|
||||
and edx,3
|
||||
dec dl
|
||||
xor dl,3
|
||||
sub ecx,edx
|
||||
|
||||
??aligned:
|
||||
mov edx,ecx
|
||||
shr ecx,2
|
||||
rep stosd
|
||||
|
||||
and edx,3
|
||||
jz ??loop
|
||||
mov ecx,edx
|
||||
rep stosb
|
||||
jmp ??loop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
??notrunlength:
|
||||
cmp al,0FFh ; is it a long run?
|
||||
jne short ??notlong ; if not use the code as the size
|
||||
|
||||
xor ecx,ecx
|
||||
xor eax,eax
|
||||
mov cx,[esi] ; if so, get the size
|
||||
lea esi,[esi+2]
|
||||
|
||||
??notlong:
|
||||
mov ax,[esi] ;get the real index
|
||||
add eax,[a1stdest] ;add in the 1st index
|
||||
lea ebx,[esi+2] ;save the source offset
|
||||
cmp ecx,[maxlen] ;compare for overrun
|
||||
mov esi,eax ;use eax as new source
|
||||
jbe short ??runok ; if not, its ok
|
||||
|
||||
mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
|
||||
|
||||
??runok:
|
||||
test ecx,0ffe0h
|
||||
jnz ??dont_use_movsb
|
||||
rep movsb
|
||||
jmp ??loop
|
||||
|
||||
|
||||
|
||||
|
||||
??dont_use_movsb:
|
||||
lea edx,[edi+0fffffffch]
|
||||
cmp esi,edx
|
||||
ja ??use_movsb
|
||||
|
||||
test edi,3
|
||||
jz ??aligned2
|
||||
|
||||
mov eax,[esi]
|
||||
mov [edi],eax
|
||||
mov edx,edi
|
||||
and edi,0fffffffch
|
||||
lea edi,[edi+4]
|
||||
and edx,3
|
||||
dec dl
|
||||
xor dl,3
|
||||
sub ecx,edx
|
||||
add esi,edx
|
||||
|
||||
??aligned2:
|
||||
mov edx,ecx
|
||||
shr ecx,2
|
||||
and edx,3
|
||||
rep movsd
|
||||
mov ecx,edx
|
||||
??use_movsb:
|
||||
rep movsb
|
||||
jmp ??loop
|
||||
|
||||
|
||||
|
||||
|
||||
??exit:
|
||||
mov eax,edi
|
||||
mov ebx,[dest]
|
||||
sub eax,ebx
|
||||
|
||||
ret
|
||||
|
||||
ENDP LCW_Uncompress
|
||||
|
||||
;***********************************************************
|
||||
|
||||
|
||||
END
|
||||
|
||||
217
WIN32LIB/SRCDEBUG/LIB.CPP
Normal file
217
WIN32LIB/SRCDEBUG/LIB.CPP
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: g:/library/source/rcs/./lib.c 1.16 1994/05/20 15:34:33 joe_bostic Exp $ */
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Library Routines *
|
||||
* *
|
||||
* File Name : LIB.C *
|
||||
* *
|
||||
* Programmer : Scott Bowen *
|
||||
* *
|
||||
* Start Date : January 14, 1993 *
|
||||
* *
|
||||
* Last Update : May 20, 1993 [PWG] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Add_Long_To_Pointer -- Pointer arithmatic when pointer could be XMS. *
|
||||
* Find_Argv -- Checks to see if string is in arguement *
|
||||
* Mono_Mem_Dump -- Dumps memory to mono monitor with hex and char. *
|
||||
* Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
|
||||
* Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
|
||||
* Set_Search_Drives -- Sets up the CDRom and HardDrive paths. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include <dos.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "misc.h"
|
||||
|
||||
//PRIVATE unsigned Divide_With_Round(unsigned num, unsigned den);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Divide_With_Round -- Divides integers and round to nearest integer. *
|
||||
* *
|
||||
* INPUT: int numberator. *
|
||||
* int denominator. *
|
||||
* *
|
||||
* OUTPUT: Returns value rounded. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/13/1992 SB : Created. *
|
||||
*=========================================================================*/
|
||||
static unsigned Divide_With_Round(unsigned num, unsigned den)
|
||||
{
|
||||
// return num/den + (0 ro 1). 1 if the remainder is more than half the denominator.
|
||||
return( (num / den) + (unsigned)((num % den) >= ((den + 1) >> 1)) );
|
||||
}
|
||||
|
||||
#define HSV_BASE 255 // This is used to get a little better persion on HSV conversion.
|
||||
#define RGB_BASE 63 // Not 64, this is really the max value.
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Convert_RGB_To_HSV -- Converts RGB to RSV coordinates. *
|
||||
* *
|
||||
* INPUT: int r,g, and b values. *
|
||||
* int *h, *s, and *v pointers. *
|
||||
* *
|
||||
* OUTPUT: Assigns values to *h, *s, and *v. *
|
||||
* *
|
||||
* WARNINGS: The reason we use a different base for HSV then RGB is *
|
||||
* because we loose alot of persision by not using floating *
|
||||
* point. Using the same base value (63) made it so that *
|
||||
* about 50% of the time one RGB value would be one different *
|
||||
* then the original if you went from RGB to HSV to RGB. *
|
||||
* Using 255 drop it down to about 9% of the time we get an *
|
||||
* off value. To get it perfect, we would have to make the *
|
||||
* HSV base larger - but then you need to do all calculations *
|
||||
* in long instead of unsigned int. *
|
||||
* HISTORY: *
|
||||
* 02/11/1992 SB : Created. *
|
||||
*=========================================================================*/
|
||||
void Convert_RGB_To_HSV(unsigned int r, unsigned int g, unsigned int b, unsigned int *h, unsigned int *s, unsigned int *v)
|
||||
{
|
||||
unsigned int m, r1, g1, b1, tmp;
|
||||
|
||||
// Convert RGB base to HSV base.
|
||||
r = Divide_With_Round((r * HSV_BASE), RGB_BASE);
|
||||
g = Divide_With_Round((g * HSV_BASE), RGB_BASE);
|
||||
b = Divide_With_Round((b * HSV_BASE), RGB_BASE);
|
||||
|
||||
// Set hue to default.
|
||||
*h = 0;
|
||||
|
||||
// Set v = Max(r,g,b) to find dominant primary color.
|
||||
*v = (r > g) ? r : g;
|
||||
if (b > *v) *v = b;
|
||||
|
||||
// Set m = min(r,g,b) to find amount of white.
|
||||
m = (r < g) ? r : g;
|
||||
if (b < m) m = b;
|
||||
|
||||
// Determine the normalized saturation.
|
||||
if (*v != 0) {
|
||||
*s = Divide_With_Round( (*v - m) * HSV_BASE ,*v);
|
||||
} else {
|
||||
*s = 0;
|
||||
}
|
||||
|
||||
if (*s != 0) {
|
||||
tmp = *v - m;
|
||||
r1 = Divide_With_Round( (*v - r) * HSV_BASE, tmp);
|
||||
g1 = Divide_With_Round( (*v - g) * HSV_BASE, tmp);
|
||||
b1 = Divide_With_Round( (*v - b) * HSV_BASE, tmp);
|
||||
|
||||
// Find effect of second most predominant color.
|
||||
// In which section of the hexagon of colors does the color lie?
|
||||
if ((*v) == r) {
|
||||
if (m == g) {
|
||||
*h = 5 * HSV_BASE + b1;
|
||||
} else {
|
||||
*h = 1 * HSV_BASE - g1;
|
||||
}
|
||||
} else {
|
||||
if ((*v) == g) {
|
||||
if (m == b) {
|
||||
*h = 1 * HSV_BASE + r1;
|
||||
} else {
|
||||
*h = 3 * HSV_BASE - b1;
|
||||
}
|
||||
} else {
|
||||
// *v == b
|
||||
if (m == r) {
|
||||
*h = 3 * HSV_BASE + g1;
|
||||
} else {
|
||||
|
||||
*h = 5 * HSV_BASE - r1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divide by six and round.
|
||||
*h = Divide_With_Round(*h, 6);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Convert_HSV_To_RGB -- Converts HSV cordinates to RGB values *
|
||||
* *
|
||||
* INPUT: int h,s, and v coordinates *
|
||||
* int *r, *g, and *b pointers. *
|
||||
* *
|
||||
* OUTPUT: Assigns values to *r, *g, and *b. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/11/1992 SB : Created. *
|
||||
*=========================================================================*/
|
||||
void Convert_HSV_To_RGB(unsigned int h, unsigned int s, unsigned int v, unsigned int *r, unsigned int *g, unsigned int *b)
|
||||
{
|
||||
unsigned int i; // Integer part.
|
||||
unsigned int f; // Fractional or remainder part. f/HSV_BASE gives fraction.
|
||||
unsigned int tmp; // Tempary variable to help with calculations.
|
||||
unsigned int values[7]; // Possible rgb values. Don't use zero.
|
||||
|
||||
|
||||
h *= 6;
|
||||
f = h % HSV_BASE;
|
||||
|
||||
// Set up possible red, green and blue values.
|
||||
values[1] =
|
||||
values[2] = v;
|
||||
|
||||
//
|
||||
// The following lines of code change
|
||||
// values[3] = (v * (HSV_BASE - ( (s * f) / HSV_BASE) )) / HSV_BASE;
|
||||
// values[4] = values[5] = (v * (HSV_BASE - s)) / HSV_BASE;
|
||||
// values[6] = (v * (HSV_BASE - (s * (HSV_BASE - f)) / HSV_BASE)) / HSV_BASE;
|
||||
// so that the are rounded divides.
|
||||
//
|
||||
|
||||
tmp = Divide_With_Round(s * f, HSV_BASE);
|
||||
values[3] = Divide_With_Round(v * (HSV_BASE - tmp), HSV_BASE);
|
||||
|
||||
values[4] =
|
||||
values[5] = Divide_With_Round(v * (HSV_BASE - s), HSV_BASE);
|
||||
|
||||
tmp = HSV_BASE - Divide_With_Round(s * (HSV_BASE - f), HSV_BASE);
|
||||
values[6] = Divide_With_Round(v * tmp, HSV_BASE);
|
||||
|
||||
|
||||
// This should not be rounded.
|
||||
i = h / HSV_BASE;
|
||||
|
||||
i += (i > 4) ? -4 : 2;
|
||||
*r = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
|
||||
|
||||
i += (i > 4) ? -4 : 2;
|
||||
*b = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
|
||||
|
||||
i += (i > 4) ? -4 : 2;
|
||||
*g = Divide_With_Round(values[i] * RGB_BASE, HSV_BASE);
|
||||
}
|
||||
378
WIN32LIB/SRCDEBUG/LOAD.CPP
Normal file
378
WIN32LIB/SRCDEBUG/LOAD.CPP
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: g:/library/wwlib32/file/rcs/load.cpp 1.4 1994/04/22 12:42:21 scott_bowen Exp $ */
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : LIBRARY *
|
||||
* *
|
||||
* File Name : LOAD.C *
|
||||
* *
|
||||
* Programmer : Christopher Yates *
|
||||
* *
|
||||
* Last Update : September 17, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Load_Uncompress -- Load and uncompress the given file. *
|
||||
* Uncompress_Data -- Uncompress standard CPS buffer. *
|
||||
* Load_Data -- Loads a data file from disk. *
|
||||
* Load_Alloc_Data -- Loads and allocates buffer for a file. *
|
||||
* Write_Data -- Writes a block of data as a file to disk. *
|
||||
* Uncompress_Data -- Uncompresses data from one buffer to another. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "iff.h"
|
||||
#include "file.h"
|
||||
#include <misc.h>
|
||||
#include <wwstd.h>
|
||||
#include <dos.h>
|
||||
#include <wwmem.h>
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
/***************************************************************************
|
||||
* LOAD_DATA -- Loads a data file from disk. *
|
||||
* *
|
||||
* This routine will load a data file from disk. It does no translation*
|
||||
* on the data. *
|
||||
* *
|
||||
* INPUT: name -- Pointer to ASCII filename of the data file. *
|
||||
* *
|
||||
* ptr -- Buffer to load the data file into. *
|
||||
* *
|
||||
* size -- Maximum size of the buffer (in bytes). *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes read. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/24/1991 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Load_Data(char const *name, void *ptr, unsigned long size)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = Open_File(name, READ);
|
||||
size = Read_File(fd, ptr, size);
|
||||
Close_File(fd);
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* WRITE_DATA -- Writes a block of data as a file to disk. *
|
||||
* *
|
||||
* This routine will write a block of data as a file to the disk. It *
|
||||
* is the compliment of Load_Data. *
|
||||
* *
|
||||
* INPUT: name -- Name of the file to create. *
|
||||
* *
|
||||
* ptr -- Pointer to the block of data to write. *
|
||||
* *
|
||||
* size -- Size of the data block to be written. *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes actually written. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/05/1992 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Write_Data(char const *name, void *ptr, unsigned long size)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = Open_File(name, WRITE);
|
||||
size = Write_File(fd, ptr, size);
|
||||
Close_File(fd);
|
||||
return(size);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* LOAD_ALLOC_DATA -- Loads and allocates buffer for a file. *
|
||||
* *
|
||||
* The routine will allocate a buffer and load the specified file into *
|
||||
* it. The kind of memory used for the buffer is determined by the *
|
||||
* memory allocation flags passed in. *
|
||||
* *
|
||||
* INPUT: name -- Name of the file to load. *
|
||||
* *
|
||||
* flags -- Memory allocation flags to use when allocating. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the buffer that contains the file's *
|
||||
* data. *
|
||||
* *
|
||||
* WARNINGS: A memory error could occur if regular memory flags are *
|
||||
* specified. If XMS memory is specified, then this routine *
|
||||
* could likely return NULL. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/28/1992 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
void * __cdecl Load_Alloc_Data(char const *name, MemoryFlagType flags)
|
||||
{
|
||||
int fd; // Working file handle.
|
||||
unsigned long size; // Size of the file to load.
|
||||
void *buffer; // Buffer to hold the file.
|
||||
|
||||
fd = Open_File(name, READ);
|
||||
size = File_Size(fd);
|
||||
buffer = Alloc(size, flags);
|
||||
if (buffer) {
|
||||
Read_File(fd, buffer, size);
|
||||
}
|
||||
Close_File(fd);
|
||||
return(buffer);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* LOAD_UNCOMPRESS -- Load and uncompress the given file. *
|
||||
* *
|
||||
* INPUT: char * - file name to uncompress *
|
||||
* GraphicBufferClass& - to load the source data into *
|
||||
* GraphicBufferClass& - for the picture *
|
||||
* void * - ptr for header uncompressed data *
|
||||
* *
|
||||
* OUTPUT: unsigned long size of uncompressed data *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/28/1991 CY : Created. *
|
||||
* 06/26/1991 JLB : Handles load & uncompress to same buffer. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Load_Uncompress(char const *file, BufferClass& uncomp_buff, BufferClass& dest_buff, void *reserved_data)
|
||||
{
|
||||
int fd; // Source file handle.
|
||||
unsigned int isize=0; // Size of the file.
|
||||
unsigned int skipsize; // Size of the skip data bytes.
|
||||
void *uncomp_ptr; // Source buffer pointer.
|
||||
char *newuncomp_ptr; // Adjusted source pointer.
|
||||
|
||||
|
||||
uncomp_ptr = uncomp_buff.Get_Buffer(); // get a pointer to buffer
|
||||
|
||||
/*======================================================================*/
|
||||
/* Read the file into the uncompression buffer. */
|
||||
/*======================================================================*/
|
||||
|
||||
fd = Open_File(file, READ); // Open up the file to read from
|
||||
Read_File(fd, (char *) &isize, 2L); // Read the file size
|
||||
Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in.
|
||||
isize -= 8; // Remaining data in file.
|
||||
|
||||
/*======================================================================*/
|
||||
/* Check for and read in the skip data block. */
|
||||
/*======================================================================*/
|
||||
|
||||
skipsize = *(((short *)uncomp_ptr) + 3);
|
||||
|
||||
if (reserved_data && skipsize) {
|
||||
Read_File(fd, reserved_data, (unsigned long) skipsize);
|
||||
} else {
|
||||
Seek_File(fd, skipsize, SEEK_CUR);
|
||||
}
|
||||
|
||||
*( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value.
|
||||
isize -= skipsize;
|
||||
|
||||
/*======================================================================*/
|
||||
/* If the source and dest buffer are the same, we adjust the pointer so */
|
||||
/* that the compressed data is loaded into the end of the buffer. In */
|
||||
/* this way the uncompress code can write to the same buffer. */
|
||||
/*======================================================================*/
|
||||
newuncomp_ptr = (char *)Add_Long_To_Pointer(uncomp_buff.Get_Buffer(), uncomp_buff.Get_Size() - (isize+8L));
|
||||
|
||||
/*======================================================================*/
|
||||
/* Duplicate the header bytes. */
|
||||
/*======================================================================*/
|
||||
Mem_Copy(uncomp_ptr,newuncomp_ptr,8);
|
||||
|
||||
/*======================================================================*/
|
||||
/* Read in the main compressed part of the file. */
|
||||
/*======================================================================*/
|
||||
Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize);
|
||||
Close_File(fd);
|
||||
|
||||
/*======================================================================*/
|
||||
/* Uncompress the file into the destination buffer (which may very well */
|
||||
/* be the source buffer). */
|
||||
/*======================================================================*/
|
||||
return(Uncompress_Data(newuncomp_ptr, dest_buff.Get_Buffer()));
|
||||
}
|
||||
#if(0)
|
||||
/***************************************************************************
|
||||
* LOAD_UNCOMPRESS -- Load and uncompress the given file. *
|
||||
* *
|
||||
* INPUT: char *file name to uncompress, BuffType uncomp_buff to load *
|
||||
* the source data into, BuffType dest_buff for the picture, *
|
||||
* void *reserved_data pointer for header uncompressed data *
|
||||
* *
|
||||
* OUTPUT: unsigned long size of uncompressed data *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/28/1991 CY : Created. *
|
||||
* 06/26/1991 JLB : Handles load & uncompress to same buffer. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Load_Uncompress(char const *file, BuffType uncomp_buff, BuffType dest_buff, void *reserved_data)
|
||||
{
|
||||
int fd; // Source file handle.
|
||||
unsigned int isize; // Size of the file.
|
||||
unsigned int skipsize; // Size of the skip data bytes.
|
||||
void *uncomp_ptr; // Source buffer pointer.
|
||||
char *newuncomp_ptr; // Adjusted source pointer.
|
||||
|
||||
|
||||
uncomp_ptr = Get_Buff(uncomp_buff); /* Get pointer to uncomp buffer */
|
||||
|
||||
/* Read the file into the uncomp_buff */
|
||||
|
||||
fd = Open_File(file, READ);
|
||||
Read_File(fd, (char *) &isize, 2L); /* Read the file size */
|
||||
#if(AMIGA)
|
||||
isize = Reverse_Word(isize);
|
||||
#endif
|
||||
|
||||
Read_File(fd, uncomp_ptr, 8L); // Read the header bytes in.
|
||||
isize -= 8; // Remaining data in file.
|
||||
|
||||
/*
|
||||
** Check for and read in the skip data block.
|
||||
*/
|
||||
|
||||
skipsize = *(((short*)uncomp_ptr) + 3);
|
||||
#if(AMIGA)
|
||||
skipsize = Reverse_Word(skipsize);
|
||||
#endif
|
||||
|
||||
if (reserved_data && skipsize) {
|
||||
Read_File(fd, reserved_data, (unsigned long) skipsize);
|
||||
} else {
|
||||
Seek_File(fd, skipsize, SEEK_CUR);
|
||||
}
|
||||
*( ((short *)uncomp_ptr+3) ) = 0; // K/O any skip value.
|
||||
isize -= skipsize;
|
||||
|
||||
/*
|
||||
** If the source and dest buffer are the same, we
|
||||
** adjust the pointer so that the compressed data is
|
||||
** loaded into the end of the buffer. In this way the
|
||||
** uncompress code can write to the same buffer.
|
||||
*/
|
||||
#if(IBM)
|
||||
newuncomp_ptr = (char *)Add_Long_To_Pointer(Get_Buff(uncomp_buff), PageArraySize[uncomp_buff] - (isize+8L));
|
||||
#else
|
||||
newuncomp_ptr = Get_Buff(uncomp_buff);
|
||||
newuncomp_ptr += PageArraySize[uncomp_buff] - ((isize+10) & 0xFFFE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Duplicate the header bytes.
|
||||
*/
|
||||
Mem_Copy(uncomp_ptr,newuncomp_ptr,8);
|
||||
|
||||
/*
|
||||
** Read in the main compressed part of the file.
|
||||
*/
|
||||
Read_File(fd, newuncomp_ptr + 8, (unsigned long)isize);
|
||||
Close_File(fd);
|
||||
|
||||
return(Uncompress_Data(newuncomp_ptr, Get_Buff(dest_buff)));
|
||||
}
|
||||
|
||||
#endif
|
||||
/***************************************************************************
|
||||
* Uncompress_Data -- Uncompresses data from one buffer to another. *
|
||||
* *
|
||||
* This routine takes data from a compressed file (sans the first two *
|
||||
* size bytes) and uncompresses it to a destination buffer. The source *
|
||||
* data MUST have the CompHeaderType at its start. *
|
||||
* *
|
||||
* INPUT: src -- Source compressed data pointer. *
|
||||
* *
|
||||
* dst -- Destination (paragraph aligned) pointer. *
|
||||
* *
|
||||
* OUTPUT: Returns with the size of the uncompressed data. *
|
||||
* *
|
||||
* WARNINGS: If LCW compression is used, the destination buffer must *
|
||||
* be paragraph aligned. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/17/1993 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Uncompress_Data(void const *src, void *dst)
|
||||
{
|
||||
unsigned int skip; // Number of leading data to skip.
|
||||
CompressionType method; // Compression method used.
|
||||
unsigned long uncomp_size=NULL;
|
||||
|
||||
if (!src || !dst) return(NULL);
|
||||
|
||||
/*
|
||||
** Interpret the data block header structure to determine
|
||||
** compression method, size, and skip data amount.
|
||||
*/
|
||||
uncomp_size = ((CompHeaderType*)src)->Size;
|
||||
#if(AMIGA)
|
||||
uncomp_size = Reverse_Long(uncomp_size);
|
||||
#endif
|
||||
skip = ((CompHeaderType*)src)->Skip;
|
||||
#if(AMIGA)
|
||||
skip = Reverse_Word(skip);
|
||||
#endif
|
||||
method = (CompressionType) ((CompHeaderType*)src)->Method;
|
||||
src = Add_Long_To_Pointer((void *)src, (long)sizeof(CompHeaderType) + (long)skip);
|
||||
|
||||
switch (method) {
|
||||
|
||||
default:
|
||||
case NOCOMPRESS:
|
||||
Mem_Copy((void *) src, dst, uncomp_size);
|
||||
break;
|
||||
|
||||
case HORIZONTAL:
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
RLE_Uncompress((void *) src, dst, uncomp_size);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case LCW:
|
||||
LCW_Uncompress((void *) src, (void *) dst, (unsigned long) uncomp_size);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return(uncomp_size);
|
||||
}
|
||||
|
||||
|
||||
140
WIN32LIB/SRCDEBUG/LOADFONT.CPP
Normal file
140
WIN32LIB/SRCDEBUG/LOADFONT.CPP
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : LOADFONT.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : September 6, 1991 *
|
||||
* *
|
||||
* Last Update : June 27, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Load_Font -- Loads a font from disk. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "font.h"
|
||||
#include <file.h>
|
||||
#include <wwmem.h>
|
||||
#include <wwstd.h>
|
||||
|
||||
#if(IBM)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int FontXSpacing = 0;
|
||||
int FontYSpacing = 0;
|
||||
void const *FontPtr = NULL;
|
||||
char FontWidth = 8;
|
||||
char FontHeight = 8;
|
||||
|
||||
// only font.c and set_font.c use the following
|
||||
char *FontWidthBlockPtr = NULL;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* LOAD_FONT -- Loads a font from disk. *
|
||||
* *
|
||||
* This loads a font from disk. This function must be called as a *
|
||||
* precursor to calling Set_Font(). You need only call this function *
|
||||
* once per desired font at the beginning of your code, but AFTER *
|
||||
* Prog_Init() is called. *
|
||||
* *
|
||||
* INPUT: name - Pointer to font name to use (eg. "topaz.font") *
|
||||
* *
|
||||
* fontsize - Size in points of the font loaded. *
|
||||
* *
|
||||
* OUTPUT: Pointer to font data or NULL if unable to load. *
|
||||
* *
|
||||
* WARNINGS: Some system memory is grabbed by this routine. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 4/10/91 BS : 2.0 compatibily *
|
||||
* 6/09/91 JLB : IBM and Amiga compatability. *
|
||||
* 11/27/1991 JLB : Uses file I/O routines for disk access. *
|
||||
* 01/29/1992 DRD : Modified to use new font format. *
|
||||
* 02/01/1992 DRD : Added font file verification. *
|
||||
* 06/29/1994 SKB : modified for 32 bit library *
|
||||
*=========================================================================*/
|
||||
void * __cdecl Load_Font(char const *name)
|
||||
{
|
||||
char valid;
|
||||
int fh; // DOS file handle for font file.
|
||||
unsigned short size; // Size of the data in the file (-2);
|
||||
char *ptr = NULL; // Pointer to newly loaded font.
|
||||
|
||||
|
||||
|
||||
fh=Open_File(name,READ);
|
||||
if ( fh>=0 ){
|
||||
if ( Read_File(fh, (char *) &size, 2) != 2) return(NULL);
|
||||
|
||||
ptr = (char *) Alloc(size , MEM_NORMAL );
|
||||
*(short *)ptr = size;
|
||||
Read_File(fh, ptr + 2, size - 2);
|
||||
Close_File(fh);
|
||||
} else {
|
||||
return ((void*)errno);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef cuts
|
||||
if (Find_File(name)) {
|
||||
fh = Open_File(name, READ);
|
||||
if (Read_File(fh, (char *) &size, 2) != 2) return(NULL);
|
||||
|
||||
ptr = (char *) Alloc(size, MEM_NORMAL);
|
||||
*(short *)ptr = size;
|
||||
Read_File(fh, ptr + 2, size - 2);
|
||||
Close_File(fh);
|
||||
} else {
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// verify that the file loaded is a valid font file.
|
||||
//
|
||||
|
||||
valid = FALSE;
|
||||
if (*(ptr + 2) == 0) { // no compression
|
||||
if (*(ptr + 3) == 5) { // currently only 5 data blocks are used.
|
||||
valid = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !valid ) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
85
WIN32LIB/SRCDEBUG/LOADPAL.CPP
Normal file
85
WIN32LIB/SRCDEBUG/LOADPAL.CPP
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Load_Palette *
|
||||
* *
|
||||
* File Name : LOADPAL.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : April 25, 1994 *
|
||||
* *
|
||||
* Last Update : April 27, 1994 [BR] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Note: This module contains dependencies upon the file I/O system, *
|
||||
* specifically Load_Data(). *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Load_Palette -- Loads a palette file into the given palette buffer. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/*
|
||||
********************************* Includes **********************************
|
||||
*/
|
||||
#include <wwstd.h>
|
||||
#include "wwstd.h"
|
||||
#include "iff.h"
|
||||
#include "palette.h"
|
||||
|
||||
/*
|
||||
********************************* Constants *********************************
|
||||
*/
|
||||
|
||||
/*
|
||||
********************************** Globals **********************************
|
||||
*/
|
||||
|
||||
/*
|
||||
******************************** Prototypes *********************************
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
* Load_Palette -- Loads a palette file into the given palette buffer. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* BYTE * file_name - name of the file to load. *
|
||||
* BYTE * palette_pointer - pointer to palette buffer. *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/20/1991 BS : Created. *
|
||||
* 04/27/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
void __cdecl Load_Palette(char *palette_file_name, void *palette_pointer)
|
||||
{
|
||||
#if(IBM)
|
||||
Load_Data(palette_file_name, palette_pointer, 768);
|
||||
#else
|
||||
Load_Data(palette_file_name, palette_pointer, (ULONG)(2<<BIT_PLANES));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************** End of loadpal.cpp ***************************/
|
||||
188
WIN32LIB/SRCDEBUG/LOADPCX.CPP
Normal file
188
WIN32LIB/SRCDEBUG/LOADPCX.CPP
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : IFF *
|
||||
* *
|
||||
* File Name : LOADPCX.CPP *
|
||||
* *
|
||||
* Programmer : Julio R. Jerez *
|
||||
* *
|
||||
* Start Date : May 2, 1995 *
|
||||
* *
|
||||
* Last Update : May 3, 1995 [JRJ] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* GraphicBufferClass* Read_PCX_File (char* name, void *Buff, long size ); *
|
||||
* int Get_PCX_Palette (char * name, void& palette ) *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <wwlib32.h>
|
||||
#include "filepcx.h"
|
||||
|
||||
/***************************************************************************
|
||||
* READ_PCX_FILE -- read a pcx file into a Graphic Buffer *
|
||||
* *
|
||||
* GraphicBufferClass* Read_PCX_File (char* name, char* palette ,void *Buff, long size ); *
|
||||
* *
|
||||
* *
|
||||
* INPUT: name is a NULL terminated string of the fromat [xxxx.pcx] *
|
||||
* palette is optional, if palette != NULL the the color palette of *
|
||||
* the pcx file will be place in the memory block pointed *
|
||||
* by palette. *
|
||||
* Buff is optinal, if Buff == NULL a new memory Buffer *
|
||||
* will be allocated, otherwise the file will be placed *
|
||||
* at location pointd by Buffer; *
|
||||
* Size is the size in bytes of the memory block pointed by Buff *
|
||||
* is also optional;
|
||||
* *
|
||||
* OUTPUT: on succes a pointer to a GraphicBufferClass cointaining the *
|
||||
* pcx file, NULL othewise. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/03/1995 JRJ : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
#define POOL_SIZE 2048
|
||||
#define READ_CHAR() *file_ptr++ ; \
|
||||
if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
|
||||
Read_File ( file_handle, pool , POOL_SIZE ) ; \
|
||||
file_ptr = pool ; \
|
||||
}
|
||||
|
||||
|
||||
GraphicBufferClass* Read_PCX_File(char* name, char* Palette, void *Buff, long Size)
|
||||
{
|
||||
unsigned i , j ;
|
||||
unsigned rle ;
|
||||
unsigned color ;
|
||||
unsigned scan_pos ;
|
||||
char * file_ptr ;
|
||||
int width ;
|
||||
int height ;
|
||||
int file_handle ;
|
||||
char * buffer ;
|
||||
PCX_HEADER header ;
|
||||
RGB * pal ;
|
||||
char pool [ POOL_SIZE ] ;
|
||||
GraphicBufferClass * pic ;
|
||||
|
||||
// Open file name
|
||||
file_handle = Open_File ( name , READ ) ;
|
||||
if ( file_handle == WW_ERROR ) return NULL ;
|
||||
|
||||
Read_File ( file_handle, & header , sizeof (PCX_HEADER)) ;
|
||||
if ( header.id != 10 && header.version != 5 &&
|
||||
header.pixelsize != 8 ) return NULL ;
|
||||
|
||||
width = header.width - header.x + 1 ;
|
||||
height = header.height - header.y + 1 ;
|
||||
|
||||
if ( Buff ) {
|
||||
buffer = ( char * ) Buff;
|
||||
i = Size / width;
|
||||
height = MIN ( i - 1, height);
|
||||
pic = new GraphicBufferClass( width, height, buffer ,Size);
|
||||
if ( !(pic && pic->Get_Buffer()))return NULL ;
|
||||
} else {
|
||||
pic = new GraphicBufferClass( width, height, NULL, width*(height+4));
|
||||
if ( !(pic && pic->Get_Buffer()))return NULL ;
|
||||
}
|
||||
|
||||
buffer = (char *) pic->Get_Buffer() ;
|
||||
file_ptr = pool ;
|
||||
Read_File ( file_handle, pool , POOL_SIZE ) ;
|
||||
|
||||
if ( header.byte_per_line != width )
|
||||
for ( scan_pos = j = 0 ; j < height ; j ++, scan_pos += width ) {
|
||||
for ( i = 0 ; i < width ; ) {
|
||||
rle = READ_CHAR ();
|
||||
if ( rle > 192 ) {
|
||||
rle -= 192 ;
|
||||
color = READ_CHAR (); ;
|
||||
memset ( buffer + scan_pos + i , color , rle ) ;
|
||||
i += rle ;
|
||||
} else * ( buffer + scan_pos + i ++ ) = (char)rle ;
|
||||
}
|
||||
if ( i == width )
|
||||
rle = READ_CHAR () ;
|
||||
// if ( rle > 192 ) rle = READ_CHAR ();
|
||||
}
|
||||
|
||||
|
||||
else for ( i = 0 ; i < width * height ; ) {
|
||||
rle = READ_CHAR ();
|
||||
rle &= 0xff;
|
||||
if ( rle > 192 ) {
|
||||
rle -= 192 ;
|
||||
color = READ_CHAR ();
|
||||
memset ( buffer + i , color , rle ) ;
|
||||
i += rle ;
|
||||
} else * ( buffer + i ++ ) = (char)rle ;
|
||||
}
|
||||
|
||||
if ( Palette ) {
|
||||
//Seek_File ( file_handle , - 256 * sizeof ( RGB ) , SEEK_END ) ;
|
||||
Seek_File ( file_handle , 256 * sizeof ( RGB ) , SEEK_END ) ;
|
||||
Read_File ( file_handle, Palette , 256L * sizeof ( RGB )) ;
|
||||
|
||||
pal = ( RGB * ) Palette ;
|
||||
for ( i = 0 ; i < 256 ; i ++ ) {
|
||||
pal -> red >>= 2 ;
|
||||
pal -> green >>= 2 ;
|
||||
pal -> blue >>= 2 ;
|
||||
pal ++ ;
|
||||
}
|
||||
}
|
||||
Close_File (file_handle) ;
|
||||
return pic ;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* READ_PCX_FILE -- read a pcx file into a Graphic Buffer *
|
||||
* *
|
||||
* GraphicBufferClass* Read_PCX_File (char* name, BufferClass& Buff, *
|
||||
* char* palette) * *
|
||||
* *
|
||||
* *
|
||||
* INPUT: name is a NULL terminated string of the fromat [xxxx.pcx] *
|
||||
* Buff is a pointer to a BufferClass the will hold the pcx file *
|
||||
* at location pointd by Buffer; *
|
||||
* palette is optional, if palette != NULL the the color palette of *
|
||||
* the pcx file will be place in the memory block pointed *
|
||||
* by palette. *
|
||||
* *
|
||||
* OUTPUT: on succes a pointer to a GraphicBufferClass cointaining the *
|
||||
* pcx file, NULL othewise. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/03/1995 JRJ : Created. *
|
||||
*=========================================================================*/
|
||||
|
||||
GraphicBufferClass* Read_PCX_File (char* name, BufferClass& Buff,char* palette)
|
||||
{
|
||||
return Read_PCX_File(name, palette, (void*)Buff.Get_Buffer(), Buff.Get_Size());
|
||||
}
|
||||
552
WIN32LIB/SRCDEBUG/LOADPICT.CPP
Normal file
552
WIN32LIB/SRCDEBUG/LOADPICT.CPP
Normal file
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: g:/library/wwlib32/file/rcs/loadpict.cpp 1.1 1994/04/20 14:38:08 scott_bowen Exp $ */
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : IFFEXTRA.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : June 11, 1991 *
|
||||
* *
|
||||
* Last Update : April 20, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* ILBM_To_Amiga -- Convert ILBM to bitplane Amiga format. *
|
||||
* ILBM_To_MCGA -- Converts ILBM picture into MCGA format. *
|
||||
* PBM_To_Amiga -- Converts a PBM picture into Amiga format. *
|
||||
* Load_Picture -- Loads a picture file (CPS or LBM format). *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "iff.h"
|
||||
#include "file.h"
|
||||
#include <wwmem.h> // For Alloc.
|
||||
|
||||
#if(IBM)
|
||||
#include <mem.h>
|
||||
#endif
|
||||
|
||||
// Since we are not currently using AMIGA, this has been put in to
|
||||
// give us back some code space. If it is needed for a utility,
|
||||
// this module should be recompiled with that utility and set the
|
||||
// define to TRUE.
|
||||
#define MAKE_AMIGA_ART FALSE
|
||||
|
||||
/*
|
||||
** An IFF picture file can have one of two formats:
|
||||
** ILBM - InterLeaved Bit Map
|
||||
** PBM - Packed Bit Map
|
||||
*/
|
||||
typedef enum {
|
||||
FORM_ILBM,
|
||||
FORM_PBM
|
||||
} IFFForm_Type;
|
||||
|
||||
/*
|
||||
** These are the various chunks that compose an IFF picture file.
|
||||
*/
|
||||
#define ID_FORM MAKE_ID('F','O','R','M')
|
||||
#define ID_ILBM MAKE_ID('I','L','B','M')
|
||||
#define ID_PBM MAKE_ID('P','B','M',' ')
|
||||
#define ID_CMAP MAKE_ID('C','M','A','P')
|
||||
#define ID_BODY MAKE_ID('B','O','D','Y')
|
||||
#define ID_BMHD MAKE_ID('B','M','H','D')
|
||||
|
||||
|
||||
/*
|
||||
** The BMHD (Bit Map HeaDer) chunk in an IFF picture file contains the
|
||||
** information necessary to extract that picture from the BODY chunk.
|
||||
** It also indicates the size and depth of the source art.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned short W, H; // Raster width and height in pixels.
|
||||
short X, Y; // Pixel postion for this image.
|
||||
char BPlanes; // Number of bitplanes.
|
||||
unsigned char Masking; // Masking control byte.
|
||||
// 0 = No masking.
|
||||
// 1 = Has a mask.
|
||||
// 2 = Has transparent color.
|
||||
// 3 = Lasso.
|
||||
unsigned char Compression; // Compression method.
|
||||
// 0 = No compression.
|
||||
// 1 = Byte run compression.
|
||||
char pad;
|
||||
unsigned short Transparent; // Transparent color number.
|
||||
unsigned char XAspect, // Pixel aspect ratio of source art.
|
||||
YAspect;
|
||||
short PageWidth, // Source 'page' size in pixels.
|
||||
PageHeight;
|
||||
} BitMapHeader_Type;
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
PRIVATE void __cdecl ILBM_To_MCGA(BufferClass& src, BufferClass& dest, int planes);
|
||||
PRIVATE void __cdecl ILBM_To_Amiga(BufferClass& src, BufferClass& dest, int planes);
|
||||
PRIVATE void __cdecl PBM_To_Amiga(BufferClass& src, BufferClass& dest, int planes);
|
||||
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ILBM_TO_MCGA -- Converts ILBM picture into MCGA format. *
|
||||
* *
|
||||
* This converts an ILBM picture (typical of DPaint LBM files) and *
|
||||
* converts it to MCGA mode (byte per pixel). This function would be *
|
||||
* used after the body of an ILBM picture is loaded. Because the *
|
||||
* number of bitplanes can vary greatly, it is necessary to pass the *
|
||||
* bitplane count to this function. The size (320 by 200) of the *
|
||||
* source picture is presumed. *
|
||||
* *
|
||||
* INPUT: src - Buffer number for source ILBM picture. *
|
||||
* *
|
||||
* dest - Buffer number for place to put MCGA format. *
|
||||
* *
|
||||
* planes- The number of bitplanes in the ILBM picture. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/20/1994 SKB : Update to 32 bit library and make private. *
|
||||
*=========================================================================*/
|
||||
PRIVATE void __cdecl ILBM_To_MCGA(BufferClass& src, BufferClass& dest, int planes)
|
||||
{
|
||||
char *source; // Source pointer.
|
||||
char *destination; // Destination pointer.
|
||||
int index,j,i; // Working index values.
|
||||
int bplane; // Bit plane counter.
|
||||
char bytes[8]; // Byte array holding max bitplanes (8).
|
||||
char value; // Composed byte(pixel) value.
|
||||
|
||||
source = (char *) src.Get_Buffer();
|
||||
destination = (char *) dest.Get_Buffer();
|
||||
|
||||
memset(bytes, '\0', 8); // Makes sure upper bits will be clear.
|
||||
|
||||
// Each row is grouped and processed together.
|
||||
|
||||
for (index = 0; index < 200 /*bmhd.H*/; index++) {
|
||||
|
||||
// Process each line in groups of 8 bytes.
|
||||
|
||||
for (j = 0; j < 40 /*(bmhd.W>>3)*/; j++) {
|
||||
|
||||
// Get the bitplane bytes.
|
||||
|
||||
for (bplane = 0; bplane < planes /*bmhd.BPlanes*/; bplane++) {
|
||||
bytes[bplane] = *(source + (bplane * 40 /*(bmhd.W>>3)*/));
|
||||
}
|
||||
source++;
|
||||
|
||||
// Roll the bits out to create 8 pixels (by bytes).
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
// 8 bits per byte.
|
||||
value = 0;
|
||||
for (bplane = planes - 1/*bmhd.BPlanes-1*/; bplane >= 0; bplane--) {
|
||||
value <<= 1; // Make room for next bit.
|
||||
if (bytes[bplane] & 0x80) value |= 1; // Set the bit.
|
||||
bytes[bplane] <<= 1;
|
||||
}
|
||||
*destination++ = value; // Output the pixel byte.
|
||||
}
|
||||
}
|
||||
|
||||
// Advance to next scan line.
|
||||
source += 40 /* (bmhd.W >> 3)*/ * (planes /* bmhd.BPlanes */ - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ILBM_TO_AMIGA -- Convert ILBM to bitplane Amiga format. *
|
||||
* *
|
||||
* This converts an InterLeaved BitMap picture into Amiga bitplane *
|
||||
* format (8K per bitplane). The data of an ILBM picture is controlled *
|
||||
* by the number of bitplanes it contains. The bitplane count is *
|
||||
* passed into this program. *
|
||||
* *
|
||||
* INPUT: src - Buffer number for source ILBM picture data. *
|
||||
* *
|
||||
* dest - Buffer number for destination Amiga picture data. *
|
||||
* *
|
||||
* planes- The number of bitplanes in the source ILBM data. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: The amount of data placed into the destination buffer is *
|
||||
* controlled by the number of bitplanes specified. It is *
|
||||
* 8000 per bitplane. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/20/1991 JLB : Created. *
|
||||
* 04/20/1994 SKB : Update to 32 bit library and make private. *
|
||||
* 04/20/1994 SKB : #if out for main library. Only used in utils maybe. *
|
||||
*=========================================================================*/
|
||||
#if MAKE_AMIGA_ART
|
||||
PRIVATE void __cdecl ILBM_To_Amiga(BufferClass& src, BufferClass& dest, int planes)
|
||||
{
|
||||
int row; // Working row counter.
|
||||
int bp; // Working bitplane counter.
|
||||
char *srcptr, // Source buffer pointer.
|
||||
*dstptr; // Destination buffer pointer.
|
||||
|
||||
srcptr = (char *) src.Get_Buffer(); // Source buffer pointer.
|
||||
dstptr = (char *) dest.Get_Buffer(); // Destination buffer pointer.
|
||||
|
||||
for (row = 0; row < 200; row++) {
|
||||
for (bp = 0; bp < planes; bp++) {
|
||||
Mem_Copy(srcptr,dstptr+(8000*bp),40);
|
||||
srcptr += 40;
|
||||
}
|
||||
dstptr += 40;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* PBM_TO_AMIGA -- Converts a PBM picture into Amiga format. *
|
||||
* *
|
||||
* This converts a PBM (Packed Bit Map) MCGA picture into Amiga *
|
||||
* bitplane format. A PBM picture presumes 8 bitplanes, but this *
|
||||
* can be controlled by the 'plane' parameter passed in. *
|
||||
* *
|
||||
* INPUT: src - Buffer number for the source PBM data. *
|
||||
* *
|
||||
* dest - Buffer number to place the Amiga format picture. *
|
||||
* *
|
||||
* planes- The number of bitplanes to extract from the PBM source *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: The amount of data placed into the destination buffer is *
|
||||
* controlled by the number of bitplanes specified. It is *
|
||||
* 8000 per bitplane. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/20/1991 JLB : Created. *
|
||||
* 04/20/1994 SKB : Update to 32 bit library and make private. *
|
||||
* 04/20/1994 SKB : #if out for main library. Only used in utils maybe. *
|
||||
*=========================================================================*/
|
||||
#if MAKE_AMIGA_ART
|
||||
PRIVATE void __cdecl PBM_To_Amiga(BufferClass& src, BufferClass& dest, int planes)
|
||||
{
|
||||
int row, // Working row counter.
|
||||
col, // Working column (by byte) counter.
|
||||
bit; // Working bitplane counter.
|
||||
unsigned char *destptr, // Destination byte pointer.
|
||||
*srcptr; // Source byte pointer.
|
||||
unsigned char value; // Working input MCGA pixel number.
|
||||
|
||||
|
||||
destptr = (unsigned char *) dest.Get_Buffer();
|
||||
srcptr = (unsigned char *) src.Get_Buffer();
|
||||
|
||||
memset(destptr, 0, 32000);
|
||||
memset(destptr+32000, 0, 32000);
|
||||
|
||||
for (row = 0; row < 200; row++) {
|
||||
|
||||
for (col = 0; col < 320; col++) {
|
||||
value = *srcptr++;
|
||||
|
||||
for (bit = 0; bit < planes; bit++) {
|
||||
if (value & (0x01 << bit)) {
|
||||
destptr[(short)((8000L * (long)bit) + (col>>3))] |= 0x80 >> (col & 0x07);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destptr += 40;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* LOAD_PICTURE -- Loads a picture file (CPS or LBM format). *
|
||||
* *
|
||||
* This loads a picture file into a page buffer. The loaded file will *
|
||||
* be in MCGA or Amiga mode as requested. Supported source formats *
|
||||
* are CPS or all forms of IFF dpaint files. *
|
||||
* *
|
||||
* INPUT: filename - Source filename. The only files that are *
|
||||
* processed as IFF are those files that end with *
|
||||
* ".LBM". *
|
||||
* *
|
||||
* loadbuf - Buffer type number for the temporary loading *
|
||||
* buffer. It will be trashed. *
|
||||
* *
|
||||
* destbuf - Buffer type number for the picture to be placed. *
|
||||
* *
|
||||
* palette - Palette buffer pointer. If this value is NULL *
|
||||
* then no palette is loaded. *
|
||||
* *
|
||||
* format - Desired destination format. *
|
||||
* BM_AMIGA - Destination buffer will contain the *
|
||||
* picture in bitplane format (Amiga). *
|
||||
* The buffer will contain data equal to *
|
||||
* 8K times the number of bit planes. *
|
||||
* *
|
||||
* BM_MCGA - Destination buffer will contain the *
|
||||
* picture in MCGA format (byte per pixel).*
|
||||
* The buffer will be 64K in size. *
|
||||
* *
|
||||
* OUTPUT: int number of bitplanes read into the dest buffer *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 05/20/1991 JLB : Handles Amiga and IBM destination formats. *
|
||||
*=========================================================================*/
|
||||
int __cdecl Load_Picture(char const *filename, BufferClass& scratchbuf, BufferClass& destbuf, unsigned char *palette, PicturePlaneType format)
|
||||
{
|
||||
int fh; // Input file handle.
|
||||
long ifftype; // Iff form type.
|
||||
int counter; // Count of the bytes decompressed.
|
||||
int value; // Working compression code value.
|
||||
int len; // int sized length value.
|
||||
int index; // Working index values.
|
||||
BitMapHeader_Type bmhd; // BMHD chunk data.
|
||||
IFFForm_Type formtype; // ILBM, PBM.
|
||||
char *src; // Working source body pointer.
|
||||
char *dest; // Working destination body pointer.
|
||||
|
||||
|
||||
//len = strlen(filename);
|
||||
//strupr(filename);
|
||||
|
||||
fh = Open_File(filename,READ);
|
||||
if (fh == WW_ERROR) return(FALSE);
|
||||
Read_File(fh,&ifftype,4L);
|
||||
Close_File(fh);
|
||||
|
||||
if (ifftype != ID_FORM) {
|
||||
return((int)Load_Uncompress(filename, scratchbuf, destbuf, palette ) / 8000 ) ;
|
||||
} else {
|
||||
|
||||
fh = Open_Iff_File(filename); // Opens and checks for IFF form.
|
||||
if (fh == WW_ERROR) return(FALSE);
|
||||
|
||||
Read_File(fh, &ifftype, 4L);
|
||||
if (ifftype == ID_ILBM) {
|
||||
formtype = FORM_ILBM; // Inter-Leaved Bit Map.
|
||||
} else {
|
||||
if (ifftype == ID_PBM) {
|
||||
formtype = FORM_PBM; // Packed Bit Map.
|
||||
} else {
|
||||
return FALSE; // Not a recognizable picture file.
|
||||
}
|
||||
}
|
||||
|
||||
// Load the BMHD chunk.
|
||||
if (Read_Iff_Chunk(fh,ID_BMHD,(char*)&bmhd,sizeof(BitMapHeader_Type))) {
|
||||
|
||||
#if(IBM)
|
||||
// Perform necessary IBM conversions to the data.
|
||||
bmhd.W = Reverse_Short(bmhd.W);
|
||||
bmhd.H = Reverse_Short(bmhd.H);
|
||||
bmhd.X = Reverse_Short(bmhd.X);
|
||||
bmhd.Y = Reverse_Short(bmhd.Y);
|
||||
|
||||
// this is a mistake Xaspect and YAspect are char type
|
||||
// bmhd.XAspect = Reverse_Short(bmhd.XAspect);
|
||||
// bmhd.YAspect = Reverse_Short(bmhd.YAspect);
|
||||
value = bmhd.XAspect ;
|
||||
bmhd.XAspect = bmhd.YAspect ;
|
||||
bmhd.YAspect = ( unsigned char ) value ;
|
||||
|
||||
bmhd.PageWidth = Reverse_Short(bmhd.PageWidth);
|
||||
bmhd.PageHeight = Reverse_Short(bmhd.PageHeight);
|
||||
#endif
|
||||
|
||||
if (bmhd.Masking > 2) return FALSE; // Don't allow brushes.
|
||||
if (bmhd.Compression > 1) return FALSE; // Unknown compression.
|
||||
|
||||
} else {
|
||||
return FALSE; // Unable to read the required BMHD chunk.
|
||||
}
|
||||
|
||||
// Load the palette if asked.
|
||||
if (palette)
|
||||
{
|
||||
int pbytes ; // Number of CMAP bytes required.
|
||||
unsigned char color; // Palette color value.
|
||||
unsigned char *paletteptr; // Allocated buffer for palette conversions.
|
||||
unsigned char *source; // Scratch source CMAP data pointer.
|
||||
unsigned char *dest2; // Scratch destination palette pointer.
|
||||
|
||||
// Number of CMAP bytes that are needed.
|
||||
pbytes = (1 << bmhd.BPlanes) * 3;
|
||||
|
||||
// Allocate the temporary palette buffer.
|
||||
paletteptr = (unsigned char *)Alloc(pbytes, MEM_CLEAR);
|
||||
source = paletteptr;
|
||||
dest2 = palette;
|
||||
|
||||
// Read in only the bytes that are needed.
|
||||
pbytes = (int)Read_Iff_Chunk(fh, ID_CMAP, (char *) paletteptr, pbytes);
|
||||
|
||||
if (pbytes) {
|
||||
|
||||
/*
|
||||
** CMAP to machine specific palette conversion code. Conversion
|
||||
** goes from CMAP three bytes per color register to the machine
|
||||
** specific form.
|
||||
*/
|
||||
switch(format) {
|
||||
default:
|
||||
case BM_MCGA:
|
||||
// Convert CMAP to IBM MCGA palette form.
|
||||
for (index = 0; index < pbytes; index++) {
|
||||
*dest2++ = *source++ >> 2;
|
||||
}
|
||||
break;
|
||||
#if MAKE_AMIGA_ART
|
||||
|
||||
case BM_AMIGA:
|
||||
// Convert CMAP to Amiga nibble packed palette form.
|
||||
for (index = 0; index < pbytes; index += 3) {
|
||||
*dest2++ = *(source++) >> 4;
|
||||
color = (*(source++) & 0xf0);
|
||||
color += *(source++) >> 4;
|
||||
*dest2++ = color;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Free(paletteptr);
|
||||
}
|
||||
|
||||
|
||||
// Load in BODY chunk.
|
||||
dest = (char *) scratchbuf.Get_Buffer();
|
||||
src = (char *) destbuf.Get_Buffer();
|
||||
|
||||
if (Read_Iff_Chunk(fh, ID_BODY, src, destbuf.Get_Size()))
|
||||
{
|
||||
for (index = 0; index < (short)bmhd.H; index++)
|
||||
{
|
||||
/* Height of source */
|
||||
// Transfer (possibly uncompress) one row of data.
|
||||
// PBM or ILBM reader. Bytes per row (all bitplanes).
|
||||
|
||||
counter = bmhd.BPlanes * (bmhd.W >> 3);
|
||||
|
||||
// If there is a mask then there is one more bitplane.
|
||||
if (bmhd.Masking == 1)
|
||||
counter += bmhd.W >> 3 ;
|
||||
|
||||
if (bmhd.Compression == 1)
|
||||
{
|
||||
// The data is compressed.
|
||||
// Decompress one scanline (all bitplanes) at a time.
|
||||
while (counter)
|
||||
{
|
||||
value = ( signed char ) *src++; // Decompression code.
|
||||
if (value == -128) continue; // NOOP code.
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
// Copy N+1 bytes.
|
||||
len = ((short) value) + 1;
|
||||
|
||||
// Ignore the masking bitplane.
|
||||
if ( bmhd.Masking != 1 ||
|
||||
(bmhd.Masking==1 && counter > ((short)bmhd.W >> 3) ) )
|
||||
{
|
||||
memcpy(dest, src, len);
|
||||
dest += len;
|
||||
}
|
||||
counter -= len;
|
||||
src += len;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replicate -N+1 bytes.
|
||||
len = (-((short) value)) + 1;
|
||||
value = *src++;
|
||||
|
||||
// Ignore the masking bitplane.
|
||||
if (bmhd.Masking != 1 || (bmhd.Masking==1 && counter > ((short)bmhd.W >> 3)))
|
||||
{
|
||||
memset(dest,value,len);
|
||||
dest += len;
|
||||
}
|
||||
counter -= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Plain data is just copied.
|
||||
memcpy(dest,src,counter);
|
||||
dest += counter;
|
||||
src += counter;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Perform necessary conversions to the data in order to reach
|
||||
** the desired format.
|
||||
*/
|
||||
switch (format) {
|
||||
default:
|
||||
case BM_MCGA: // Byte per pixel desired.
|
||||
if (formtype == FORM_ILBM) {
|
||||
ILBM_To_MCGA(scratchbuf, destbuf, bmhd.BPlanes);
|
||||
} else {
|
||||
Mem_Copy(scratchbuf.Get_Buffer(), destbuf.Get_Buffer(), 64000L);
|
||||
}
|
||||
break;
|
||||
|
||||
#if MAKE_AMIGA_ART
|
||||
case BM_AMIGA: // Bitplane format desired.
|
||||
if (formtype == FORM_ILBM) {
|
||||
ILBM_To_Amiga(scratchbuf, destbuf, bmhd.BPlanes);
|
||||
} else {
|
||||
PBM_To_Amiga(scratchbuf, destbuf, bmhd.BPlanes);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Close_Iff_File(fh);
|
||||
}
|
||||
|
||||
return((short)bmhd.BPlanes); // Loaded the picture successfully.
|
||||
}
|
||||
1089
WIN32LIB/SRCDEBUG/MEM.CPP
Normal file
1089
WIN32LIB/SRCDEBUG/MEM.CPP
Normal file
File diff suppressed because it is too large
Load Diff
184
WIN32LIB/SRCDEBUG/MEM_COPY.ASM
Normal file
184
WIN32LIB/SRCDEBUG/MEM_COPY.ASM
Normal file
@@ -0,0 +1,184 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : LIBRARY *
|
||||
;* *
|
||||
;* File Name : MEM_COPY.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott Bowen *
|
||||
;* *
|
||||
;* Last Update : September 8, 1994 [IML] *
|
||||
;* Ported to watcom c32 : 01/03/96 [JRJ] *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Mem_Copy -- Copies from one pointer to another. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
LOCALS ??
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; Much testing was done to determine that only when there are 14 or more bytes
|
||||
; being copied does it speed the time it takes to do copies in this algorithm.
|
||||
; For this reason and because 1 and 2 byte copies crash, is the special case
|
||||
; used. SKB 4/21/94. Tested on 486 66mhz.
|
||||
OPTIMAL_BYTE_COPY equ 14
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; External declares so these functions can be called
|
||||
;
|
||||
GLOBAL C Mem_Copy : NEAR
|
||||
GLOBAL C Largest_Mem_Block : near
|
||||
|
||||
CODESEG
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MEM_COPY -- Copies from one pointer to another. *
|
||||
;* This routine copies bytes from source to dest. It takes care of *
|
||||
;* overlapped memory, and unsigned long copies. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/18/1994 SKB : Created. *
|
||||
;*=========================================================================*
|
||||
; void Mem_Copy(void *source, void *dest, unsigned long bytes_to_copy);
|
||||
|
||||
|
||||
PROC Mem_Copy C near
|
||||
USES ecx , esi , edi , ebx
|
||||
ARG source:DWORD
|
||||
ARG dest:DWORD
|
||||
ARG bytes:DWORD
|
||||
|
||||
;********************************* Setup ******************************************
|
||||
cld
|
||||
mov esi,[source]
|
||||
mov edi,[dest]
|
||||
mov ecx,[bytes] ; get number of bytes to copy.
|
||||
|
||||
; check pointers for singularities
|
||||
cmp esi,edi ; Compare source with dest.
|
||||
je ??done ; No sence in copying the same pointer.
|
||||
or esi,0
|
||||
jz ??done
|
||||
or edi,0
|
||||
jz ??done
|
||||
|
||||
cmp ecx,OPTIMAL_BYTE_COPY ; see notes above about equate.
|
||||
jge ??normal ; If >= MAX(2,OPTIMAL_BYTE_COPY), do normal dword copy.
|
||||
|
||||
;******************************** Special case <= 2 *******************************
|
||||
;
|
||||
; This section must be called for bytes <= 2 since the other case will crash. It
|
||||
; optionally uses OPTIMAL_BYTE_COPY for the cut off point. This is because after
|
||||
; extensive testing, it was proved that only at that point (14 or more bytes) does
|
||||
; it become quicker to use the dword copy method.
|
||||
|
||||
cmp esi,edi ; Compare source with dest.
|
||||
jge ??do_move ; if source greater do forward copy.
|
||||
lea esi,[esi+ecx-1]
|
||||
std ; Opps, wrong, force the pointers to decrement.
|
||||
lea edi,[edi+ecx-1]
|
||||
??do_move:
|
||||
rep movsb ; move the one or two bytes.
|
||||
cld
|
||||
??done:
|
||||
ret
|
||||
|
||||
;************************** back or forth, that is the question *******************
|
||||
|
||||
??normal:
|
||||
mov ebx,ecx
|
||||
cmp esi,edi ; Compare source with dest.
|
||||
jge ??forward ; if source greater do forward copy.
|
||||
|
||||
;********************************* Backward ***************************************
|
||||
??backward:
|
||||
lea ecx,[edi+ebx]
|
||||
std
|
||||
lea edi,[edi+ebx-1]
|
||||
and ecx,3 ; Get non aligned bytes.
|
||||
lea esi,[esi+ebx-1]
|
||||
sub ebx,ecx ; remove that from the total size to be copied later.
|
||||
rep movsb ; do the copy.
|
||||
sub esi,3
|
||||
mov ecx,ebx ; Get number of bytes left.
|
||||
sub edi,3
|
||||
shr ecx,2 ; Do 4 bytes at a time.
|
||||
rep movsd ; do the dword copy.
|
||||
mov ecx,ebx
|
||||
add esi,3
|
||||
add edi,3
|
||||
and ecx,03h
|
||||
rep movsb ; finnish the remaining bytes.
|
||||
cld
|
||||
ret
|
||||
|
||||
;********************************* Forward ***************************************
|
||||
??forward:
|
||||
cld
|
||||
mov ecx,edi ; get destination pointer.
|
||||
neg ecx
|
||||
and ecx,3 ; Get non aligned bytes.
|
||||
sub ebx,ecx ; remove that from the total size to be copied later.
|
||||
rep movsb ; do the copy.
|
||||
mov ecx,ebx ; Get number of bytes left.
|
||||
shr ecx,2 ; Do 4 bytes at a time.
|
||||
rep movsd ; do the dword copy.
|
||||
mov ecx, ebx
|
||||
and ecx,03h
|
||||
rep movsb ; finnish the remaining bytes.
|
||||
ret
|
||||
|
||||
ENDP Mem_Copy
|
||||
IF 0
|
||||
PROC Largest_Mem_Block C near
|
||||
uses esi , edi , ebx , ecx , edx
|
||||
local mem_struct : dword : 16
|
||||
|
||||
mov eax , 0500h
|
||||
lea edi , [ mem_struct ]
|
||||
int 31h
|
||||
mov eax , [ mem_struct ]
|
||||
|
||||
ret
|
||||
ENDP Largest_Mem_Block
|
||||
ENDIF
|
||||
END
|
||||
|
||||
|
||||
|
||||
401
WIN32LIB/SRCDEBUG/MODEMREG.CPP
Normal file
401
WIN32LIB/SRCDEBUG/MODEMREG.CPP
Normal file
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Command & Conquer/ WW Library *
|
||||
* *
|
||||
* File Name : MODEMREG.CPP *
|
||||
* *
|
||||
* Programmer : Steve Tall *
|
||||
* *
|
||||
* Start Date : 10/18/96 *
|
||||
* *
|
||||
* Last Update : October 18th 1996 [ST] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Overview: *
|
||||
* *
|
||||
* Functions for obtaining modem infommation from the Win95 registry *
|
||||
* *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Functions: *
|
||||
* *
|
||||
* Search_Registry_Key -- Search a registry key and all its subkeys for a given value *
|
||||
* MREC::ModemRegistryEntryClass -- Constructor for ModemRegistryEntryClass *
|
||||
* MREC::~ModemRegistryEntryClass -- Destructor.Free all the memory we allocated for modem info*
|
||||
* *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "modemreg.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern HKEY Get_Registry_Sub_Key (HKEY base_key, char *search_key, BOOL close);
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Search_Registry_Key -- Search a registry key and all its subkeys for a given value *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: handle to key to search in *
|
||||
* name of key to search for *
|
||||
* value expected in key *
|
||||
* *
|
||||
* OUTPUT: Handle to key containing value. Null if not found. *
|
||||
* *
|
||||
* WARNINGS: This function reenters itself. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/96 4:01AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
HKEY Search_Registry_Key (HKEY key_in, char *value_name, char *search_string)
|
||||
{
|
||||
|
||||
int top_key_index = 0; // Index of topmost key
|
||||
int retval; // Result of registry api calls
|
||||
HKEY next_key; // handle of next key examine
|
||||
HKEY next_search; // handle of next key to search
|
||||
|
||||
|
||||
char *subkey_name = new char [256]; // Area to contain result of key enumeration
|
||||
unsigned long subkey_name_length = 256; // Length of enumeration result area
|
||||
FILETIME filetime; // Time key was last touched. Not used.
|
||||
unsigned long value_type; // Type of data that is contained in a key.
|
||||
unsigned char *key_value = new unsigned char [256]; // Area to return key values into
|
||||
unsigned long key_value_length = 256; // Length of key value area
|
||||
|
||||
/*
|
||||
** Scan through and enumerate all subkeys of this key. Exit the loop when there are
|
||||
** no more sub keys to enumerate.
|
||||
*/
|
||||
do {
|
||||
subkey_name_length = 256; // Has to be set each time through the loop
|
||||
|
||||
/*
|
||||
** Get the next key
|
||||
*/
|
||||
retval = RegEnumKeyEx (key_in, top_key_index++, subkey_name, &subkey_name_length, NULL, NULL, NULL, &filetime);
|
||||
|
||||
if ( retval == ERROR_SUCCESS ){
|
||||
|
||||
/*
|
||||
** Get a handle to this key so we can search it.
|
||||
*/
|
||||
next_key = Get_Registry_Sub_Key (key_in, subkey_name, FALSE);
|
||||
|
||||
if (next_key){
|
||||
|
||||
key_value_length = 256; // Has to be set each time through the loop
|
||||
|
||||
if ( RegQueryValueEx (next_key, value_name, NULL, &value_type, key_value, &key_value_length) == ERROR_SUCCESS){
|
||||
|
||||
/*
|
||||
** If this value is type string then do a compare with the value we are looking for
|
||||
*/
|
||||
if (value_type == REG_SZ && !strcmp ((char*)key_value, search_string)){
|
||||
/*
|
||||
** This is our man. Delete our workspace and return the key handle
|
||||
*/
|
||||
delete [] subkey_name;
|
||||
delete [] key_value;
|
||||
return (next_key);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** We didnt find our search value so search this key for more sub keys by reentering
|
||||
** this function with the handle of the subkey.
|
||||
*/
|
||||
next_search = Search_Registry_Key (next_key, value_name, search_string);
|
||||
RegCloseKey (next_key);
|
||||
|
||||
/*
|
||||
** If the value was found in a subkey then just return with the key handle.
|
||||
*/
|
||||
if (next_search){
|
||||
delete [] subkey_name;
|
||||
delete [] key_value;
|
||||
return (next_search);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} while (retval == ERROR_SUCCESS);
|
||||
|
||||
/*
|
||||
** Clean up and exit.
|
||||
*/
|
||||
delete [] subkey_name;
|
||||
delete [] key_value;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MREC::ModemRegistryEntryClass -- Constructor for ModemRegistryEntryClass *
|
||||
* *
|
||||
* This function does all the work in the class. All the registry searching is done here *
|
||||
* *
|
||||
* INPUT: Modem number *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/96 4:12AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
ModemRegistryEntryClass::ModemRegistryEntryClass (int modem_number)
|
||||
{
|
||||
HKEY key;
|
||||
unsigned char return_buf[256];
|
||||
DWORD retbuf_size = sizeof(return_buf);
|
||||
|
||||
int pnp = 0; //Not a plug n pray modem
|
||||
|
||||
/*
|
||||
** Initialise all the info we expect from the registry to NULL.
|
||||
** Any entries we cant find will just stay NULL.
|
||||
*/
|
||||
ModemName = NULL;
|
||||
ModemDeviceName = NULL;
|
||||
ErrorCorrectionEnable = NULL;
|
||||
ErrorCorrectionDisable = NULL;
|
||||
CompressionEnable = NULL;
|
||||
CompressionDisable = NULL;
|
||||
HardwareFlowControl = NULL;
|
||||
NoFlowControl = NULL;
|
||||
|
||||
|
||||
/*
|
||||
** Modem info is stored under
|
||||
** HKEY_LOCAL_MACHINE / System / CurrentControlSet / Services / Class / Modem / nnnn
|
||||
** where nnnn is a four digit modem number.
|
||||
*/
|
||||
|
||||
key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "System", FALSE);
|
||||
if (!key) return;
|
||||
|
||||
key = Get_Registry_Sub_Key (key, "CurrentControlSet", TRUE);
|
||||
if (!key) return;
|
||||
|
||||
key = Get_Registry_Sub_Key (key, "Services", TRUE);
|
||||
if (!key) return;
|
||||
|
||||
key = Get_Registry_Sub_Key (key, "Class", TRUE);
|
||||
if (!key) return;
|
||||
|
||||
key = Get_Registry_Sub_Key (key, "Modem", TRUE);
|
||||
if (!key) return;
|
||||
|
||||
char which_modem[5];
|
||||
sprintf (which_modem, "%04d", modem_number);
|
||||
|
||||
/*
|
||||
** Get a handle to the modem key if it exists. Then extract the info we need.
|
||||
*/
|
||||
key = Get_Registry_Sub_Key (key, which_modem, TRUE);
|
||||
if (!key) return;
|
||||
|
||||
|
||||
/*
|
||||
** Get the name of the modem. This is what will be displayed in the modem list presented
|
||||
** to the user.
|
||||
*/
|
||||
if (RegQueryValueEx(key, "Model", NULL, NULL, return_buf, &retbuf_size) != ERROR_SUCCESS){
|
||||
RegCloseKey (key);
|
||||
return;
|
||||
}
|
||||
ModemName = new char [retbuf_size];
|
||||
memcpy (ModemName, return_buf, retbuf_size);
|
||||
|
||||
/*
|
||||
** Find out what COM port the modem is attached to. If this info isnt here, then its a
|
||||
** Plug n Pray modem. Set the flag so we know to do the pnp search later.
|
||||
*/
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "AttachedTo", NULL, NULL, return_buf, &retbuf_size) != ERROR_SUCCESS){
|
||||
/*
|
||||
** Must be a plug n pray modem. Set the flag. We will look for the port later.
|
||||
*/
|
||||
pnp = 1;
|
||||
ModemDeviceName = new char [strlen (ModemName)+1];
|
||||
strcpy (ModemDeviceName, ModemName);
|
||||
}else{
|
||||
ModemDeviceName = new char [retbuf_size];
|
||||
memcpy (ModemDeviceName, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** The list of modem 'AT' commands is stored in the 'Settings' key.
|
||||
*/
|
||||
key = Get_Registry_Sub_Key (key, "Settings", TRUE);
|
||||
if (!key) return;
|
||||
|
||||
|
||||
/*
|
||||
** Extract the control strings for error control.
|
||||
*/
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "ErrorControl_On", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
ErrorCorrectionEnable = new char [retbuf_size];
|
||||
memcpy (ErrorCorrectionEnable, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "ErrorControl_Off", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
ErrorCorrectionDisable = new char [retbuf_size];
|
||||
memcpy (ErrorCorrectionDisable, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
/*
|
||||
** Extract the control strings for data compression.
|
||||
*/
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "Compression_On", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
CompressionEnable = new char [retbuf_size];
|
||||
memcpy (CompressionEnable, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "Compression_Off", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
CompressionDisable = new char [retbuf_size];
|
||||
memcpy (CompressionDisable, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
/*
|
||||
** Extract the control strings for hardware flow control.
|
||||
*/
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "FlowControl_Hard", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
HardwareFlowControl = new char [retbuf_size];
|
||||
memcpy (HardwareFlowControl, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
/*
|
||||
** Extract the control strings for no flow control.
|
||||
*/
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(key, "FlowControl_Off", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
NoFlowControl = new char [retbuf_size];
|
||||
memcpy (NoFlowControl, return_buf, retbuf_size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RegCloseKey (key);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** If this is a plug n pray modem then we need to search for the COM port it is
|
||||
** attached to.
|
||||
*/
|
||||
if (pnp){
|
||||
|
||||
/*
|
||||
** The driver name in the HKEY_LOCAL_MACHINE / Enum section will be Modem\nnnn where nnnn
|
||||
** is a four digit modem number.
|
||||
*/
|
||||
char search_string [256] = {"Modem\\"};
|
||||
strcat (search_string, which_modem);
|
||||
|
||||
/*
|
||||
** Search through all the registry entries under HKEY_LOCAL_MACHINE / Enum
|
||||
*/
|
||||
key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "Enum", FALSE);
|
||||
if (!key) return;
|
||||
|
||||
HKEY newkey = Search_Registry_Key ( key, "Driver", search_string );
|
||||
|
||||
if (newkey){
|
||||
retbuf_size = sizeof (return_buf);
|
||||
|
||||
/*
|
||||
** Extract the PORTNAME value. This is the name of the port to use to communicate
|
||||
** with the modem.
|
||||
*/
|
||||
retbuf_size = sizeof (return_buf);
|
||||
if (RegQueryValueEx(newkey, "PORTNAME", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
|
||||
|
||||
if (ModemDeviceName) delete [] ModemDeviceName;
|
||||
|
||||
ModemDeviceName = new char [retbuf_size];
|
||||
memcpy (ModemDeviceName, return_buf, retbuf_size);
|
||||
}
|
||||
}
|
||||
RegCloseKey (key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MREC::~ModemRegistryEntryClass -- Destructor.Free all the memory we allocated for modem info*
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: Nothing *
|
||||
* *
|
||||
* OUTPUT: Nothing *
|
||||
* *
|
||||
* WARNINGS: None *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/96 11:39AM ST : Created *
|
||||
*=============================================================================================*/
|
||||
ModemRegistryEntryClass::~ModemRegistryEntryClass (void)
|
||||
{
|
||||
if (ModemName) delete [] ModemName;
|
||||
if (ModemDeviceName) delete [] ModemDeviceName;
|
||||
|
||||
if (ErrorCorrectionEnable) delete [] ErrorCorrectionEnable;
|
||||
if (ErrorCorrectionDisable) delete [] ErrorCorrectionDisable;
|
||||
|
||||
if (CompressionEnable) delete [] CompressionEnable;
|
||||
if (CompressionDisable) delete [] CompressionDisable;
|
||||
|
||||
if (HardwareFlowControl) delete [] HardwareFlowControl;
|
||||
if (NoFlowControl) delete [] NoFlowControl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
845
WIN32LIB/SRCDEBUG/MONO.ASM
Normal file
845
WIN32LIB/SRCDEBUG/MONO.ASM
Normal file
@@ -0,0 +1,845 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Mono Screen system *
|
||||
;* *
|
||||
;* File Name : MONO.ASM *
|
||||
;* *
|
||||
;* Programmer : Jeff Wilson *
|
||||
;* *
|
||||
;* Start Date : March 28, 1994 *
|
||||
;* *
|
||||
;* Last Update : September 8, 1994 [IML] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;GLOBAL MonoScreen :DWORD
|
||||
;GLOBAL MonoEnabled :DWORD
|
||||
;
|
||||
;GLOBAL C Mono_Set_Cursor :NEAR
|
||||
;GLOBAL C Mono_Clear_Screen :NEAR
|
||||
;GLOBAL C Mono_Scroll :NEAR
|
||||
;GLOBAL C Mono_Put_Char :NEAR
|
||||
;GLOBAL C Mono_Draw_Rect :NEAR
|
||||
;
|
||||
;GLOBAL C _Mono_Text_Print :NEAR
|
||||
;GLOBAL C Mono_Text_Print :NEAR
|
||||
;
|
||||
;GLOBAL C Mono_Print :NEAR
|
||||
;
|
||||
;GLOBAL C Mono_View_Page :NEAR
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
LOCALS ??
|
||||
|
||||
|
||||
;
|
||||
; External declares so these functions can be called
|
||||
;
|
||||
GLOBAL MonoScreen :DWORD
|
||||
GLOBAL MonoEnabled :DWORD
|
||||
|
||||
GLOBAL Mono_Set_Cursor :NEAR ; done
|
||||
GLOBAL Mono_Clear_Screen :NEAR ; done
|
||||
GLOBAL Mono_Scroll :NEAR ; done
|
||||
GLOBAL Mono_Put_Char :NEAR ; done
|
||||
GLOBAL Mono_Draw_Rect :NEAR ; done
|
||||
GLOBAL _Mono_Text_Print :NEAR ; done
|
||||
GLOBAL Mono_Text_Print :NEAR ; done
|
||||
GLOBAL Mono_Print :NEAR ; done
|
||||
GLOBAL Mono_View_Page :NEAR ; done
|
||||
|
||||
;
|
||||
; Equates used in this file
|
||||
;
|
||||
NULL = 0 ; null code
|
||||
CR = 13 ; carriage return code
|
||||
CPL = 80 ; characters per line
|
||||
LPS = 25 ; lines per screen
|
||||
|
||||
|
||||
DATASEG
|
||||
|
||||
MonoX DD 0
|
||||
MonoY DD 0
|
||||
MonoOff DD 0
|
||||
MonoScreen DD 0b0000h ;Deffault to Real mode!
|
||||
MonoEnabled DD 0 ; Is mono printing enabled?
|
||||
|
||||
;====================================================================
|
||||
|
||||
CharData DB 0DAh,0C4h,0BFh,0B3h,0D9h,0C4h,0C0h,0B3h ; Single line
|
||||
DB 0D5h,0CDh,0B8h,0B3h,0BEh,0CDh,0D4h,0B3h ; Double horz.
|
||||
DB 0D6h,0C4h,0B7h,0BAh,0BDh,0C4h,0D3h,0BAh ; Double vert.
|
||||
DB 0C9h,0CDh,0BBh,0BAh,0BCh,0CDh,0C8h,0BAh ; Double line.
|
||||
|
||||
|
||||
; x,y,dist
|
||||
BoxData DB 1,0,0 ; Upper left corner.
|
||||
DB 1,0,1 ; Top edge.
|
||||
DB 0,1,0 ; Upper right corner.
|
||||
DB 0,1,2 ; Right edge.
|
||||
DB -1,0,0 ; Bottom right corner.
|
||||
DB -1,0,1 ; Bottom edge.
|
||||
DB 0,-1,0 ; Bottom left corner.
|
||||
DB 0,-1,2 ; Left edge.
|
||||
DB 0,0,-1 ; End of list.
|
||||
|
||||
; Mono page segment layout array.
|
||||
PageMap DD 0,1,2,3,4,5,6,7
|
||||
|
||||
;===================================================================
|
||||
|
||||
CODESEG
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* Map_Segment_To_Address_ -- Translate a 16bit Seg:Offset address to a *
|
||||
;* Linear address. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; int Map_Segment_To_Address ( unsigned seg , unsigned offset );
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_SET_CURSOR -- Sets the mono cursor to specified coordinates. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Set_Cursor(int x, int y);
|
||||
|
||||
|
||||
PROC Mono_Set_Cursor C near
|
||||
|
||||
USES eax , ebx , edx
|
||||
|
||||
ARG xpos : DWORD
|
||||
ARG ypos : DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
; sub eax,eax
|
||||
|
||||
mov eax,[ypos]
|
||||
; mov ah,CPL
|
||||
; imul ah
|
||||
lea eax , [ eax + 4 * eax ] ; multiply by CPL
|
||||
shl eax , 4
|
||||
|
||||
; sub ebx,ebx
|
||||
mov ebx,[xpos]
|
||||
add ebx,eax
|
||||
|
||||
; Update cursor position.
|
||||
mov edx,03B4h
|
||||
|
||||
mov al,0Eh ; High byte register set.
|
||||
out dx,al
|
||||
inc edx
|
||||
mov al,bh
|
||||
out dx,al ; Set high byte.
|
||||
|
||||
dec edx
|
||||
mov al,0Fh ; Low byte register set.
|
||||
out dx,al
|
||||
inc edx
|
||||
mov al,bl
|
||||
out dx,al ; Set low byte.
|
||||
|
||||
; Update the globals.
|
||||
add ebx,ebx
|
||||
mov [MonoOff],ebx
|
||||
mov eax,[xpos]
|
||||
mov [MonoX],eax
|
||||
mov eax,[ypos]
|
||||
mov [MonoY],eax
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Set_Cursor
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_CLEAR_SCREEN -- Clears the mono screen and homes cursor. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Clear_Screen(void);
|
||||
|
||||
PROC Mono_Clear_Screen C near
|
||||
|
||||
USES eax , ecx , edi
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
; mov eax,[MonoScreen] ; ES:DI = Mono RAM address.
|
||||
; mov es,ax
|
||||
; sub edi,edi
|
||||
mov edi , [ MonoScreen ]
|
||||
mov eax,02000200h ; Clear leave attrib bit normal.
|
||||
mov ecx,8000h/4 ; Number of longs to clear.
|
||||
rep stosd ; Clear the mono screen.
|
||||
|
||||
push 0
|
||||
push 0
|
||||
|
||||
call Mono_Set_Cursor
|
||||
add esp , 8
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Clear_Screen
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_SCROLL -- Scroll the mono screen up specified lines. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Scroll(DWORD lines);
|
||||
PROC Mono_Scroll C near
|
||||
|
||||
USES eax , ebx , ecx , edx , edi , esi
|
||||
ARG lines : DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
; xor eax,eax ; clear eax so no need for sign extend
|
||||
mov eax, [lines] ; get lines available
|
||||
or eax,eax ; any lines to scroll?
|
||||
je short ??fini ; =>NO
|
||||
|
||||
mov ebx,eax ; set line counter
|
||||
|
||||
mov edx,[MonoY] ; get row count
|
||||
ror edx,16 ; store it in high half of register
|
||||
mov dx,[WORD PTR MonoOff] ; get column offset
|
||||
ror edx,16
|
||||
|
||||
; mov eax,[MonoScreen] ; get selector for mono screen
|
||||
; push ds ; save off data seg for later
|
||||
; mov ds,ax ; set data source register
|
||||
; mov es,ax ; and extra source register
|
||||
|
||||
sub eax,eax ; set to clear clear line
|
||||
|
||||
??looper:
|
||||
mov ecx,(80*24) ; Number of words to move.
|
||||
|
||||
; xor edi,edi ; dst start at top of screen area
|
||||
; mov esi,80*2 ; src start at next line down
|
||||
mov edi , [ MonoScreen ]
|
||||
lea esi , [ 80 * 2 + edi ]
|
||||
rep movsw ; Scroll the screen upward.
|
||||
|
||||
dec dx ; decrement Y counter
|
||||
ror edx,16 ; switch to mono offset
|
||||
sub dx,80*2 ; fix MonoOffset
|
||||
ror edx,16 ; switch to y counter
|
||||
|
||||
mov ecx,40 ; Clear out the last line.
|
||||
rep stosd ; by storing words across it
|
||||
dec ebx ; last line?
|
||||
|
||||
jne ??looper ; =>NO
|
||||
|
||||
; reset data values
|
||||
; pop ds ; restore the ds segment
|
||||
mov [WORD PTR MonoY],dx ; store of the mono y position
|
||||
ror edx,16 ; switch to screen offset
|
||||
mov [WORD PTR MonoOff],dx ; store of the mono offset
|
||||
|
||||
??fini:
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Scroll
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_PUT_CHAR -- Output a character to the mono screen. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Put_Char(char character, int attrib=2);
|
||||
|
||||
PROC Mono_Put_Char C near
|
||||
|
||||
USES eax , edi
|
||||
|
||||
ARG character : BYTE
|
||||
ARG attrib : DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
|
||||
mov edi,[MonoOff]
|
||||
; mov eax,[MonoScreen]
|
||||
; mov es,ax ; ES:DI = First character output pointer.
|
||||
add edi , [ MonoScreen ]
|
||||
|
||||
; Output character to monochrome monitor.
|
||||
mov al,[character]
|
||||
mov ah,[BYTE PTR attrib]
|
||||
; stosw
|
||||
mov [ edi ] , ax
|
||||
|
||||
; Update cursor position.
|
||||
inc [MonoX] ; X position moves.
|
||||
|
||||
mov eax,[MonoY]
|
||||
push eax
|
||||
mov eax,[MonoX]
|
||||
push eax
|
||||
|
||||
call Mono_Set_Cursor
|
||||
add esp,8
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Put_Char
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_DRAW_RECT -- Draw a rectangle using mono characters. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Draw_Rect(int x, int y, int w, int h, int attrib=2, int thick=0);
|
||||
|
||||
PROC Mono_Draw_Rect C near
|
||||
|
||||
USES eax , ebx , ecx , esi , edi
|
||||
|
||||
ARG xpos:DWORD
|
||||
ARG ypos:DWORD
|
||||
ARG width:DWORD
|
||||
ARG height:DWORD
|
||||
ARG attrib:DWORD
|
||||
ARG thick:DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
mov esi,OFFSET BoxData
|
||||
mov edi,OFFSET CharData
|
||||
|
||||
; mov cl,3
|
||||
; sub eax,eax
|
||||
mov eax,[thick]
|
||||
and eax,011b
|
||||
shl eax,3
|
||||
add edi,eax
|
||||
|
||||
; Prep width and height.
|
||||
cmp [width],2
|
||||
jb ??fini
|
||||
|
||||
cmp [height],2
|
||||
jb ??fini
|
||||
|
||||
sub [width],2
|
||||
sub [height],2
|
||||
|
||||
; Preserve cursor position for later restore.
|
||||
mov ecx,[MonoX]
|
||||
push ecx
|
||||
mov ecx,[MonoY]
|
||||
push ecx
|
||||
|
||||
; Cursor starts at upper left corner.
|
||||
mov ecx,[ypos]
|
||||
push ecx
|
||||
mov ecx,[xpos]
|
||||
push ecx
|
||||
call Mono_Set_Cursor
|
||||
add esp,8
|
||||
|
||||
??drawloop:
|
||||
; Determine the number of characters to output.
|
||||
mov ecx,[width]
|
||||
cmp [BYTE PTR esi+2],1
|
||||
je short ??gotlen
|
||||
|
||||
mov ecx,[height]
|
||||
cmp [BYTE PTR esi+2],2
|
||||
je short ??gotlen
|
||||
|
||||
mov ecx,1
|
||||
??gotlen:
|
||||
|
||||
jecxz ??donerun
|
||||
|
||||
??runloop:
|
||||
sub ebx,ebx
|
||||
mov bl,[BYTE PTR edi]
|
||||
|
||||
; mov ebx,eax
|
||||
sub eax,eax
|
||||
mov al,[BYTE PTR attrib]
|
||||
push eax
|
||||
push ebx
|
||||
|
||||
call Mono_Put_Char
|
||||
add esp,8
|
||||
|
||||
movsx eax,[BYTE PTR esi+1]
|
||||
; cbw
|
||||
add eax,[MonoY]
|
||||
push eax
|
||||
movsx eax,[BYTE PTR esi]
|
||||
; cbw
|
||||
add eax,[MonoX]
|
||||
dec eax ; Undo cursor advance.
|
||||
push eax
|
||||
|
||||
call Mono_Set_Cursor ; Properly advance cursor.
|
||||
add esp,8
|
||||
|
||||
loop ??runloop
|
||||
|
||||
??donerun:
|
||||
|
||||
; Advance to next control entry.
|
||||
add esi,3
|
||||
inc edi
|
||||
cmp [BYTE PTR esi+2],-1
|
||||
jne ??drawloop
|
||||
|
||||
; Restore cursor to original position.
|
||||
call Mono_Set_Cursor
|
||||
add esp,8
|
||||
|
||||
??fini:
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Draw_Rect
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_TEXT_PRINT -- Prints text to the mono screen at coordinates. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Text_Print(void *text, int x, int y, int attrib, int update);
|
||||
|
||||
PROC _Mono_Text_Print C near
|
||||
|
||||
USES eax,ebx,ecx,edx,edi,esi
|
||||
|
||||
ARG text:DWORD
|
||||
ARG xpos:DWORD
|
||||
ARG ypos:DWORD
|
||||
ARG attrib:DWORD
|
||||
ARG update:DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
; Preserve cursor coordinates for later restoration.
|
||||
mov eax,[MonoY]
|
||||
push eax
|
||||
mov eax,[MonoX]
|
||||
push eax
|
||||
|
||||
cmp [text],NULL
|
||||
je ??fini
|
||||
|
||||
mov eax,[ypos]
|
||||
push eax
|
||||
mov eax,[xpos]
|
||||
push eax
|
||||
call Mono_Set_Cursor
|
||||
add esp,8
|
||||
|
||||
mov esi,[text]
|
||||
|
||||
??charloop:
|
||||
xor eax,eax
|
||||
mov al,[BYTE PTR esi] ; Fetch character to output.
|
||||
inc esi
|
||||
|
||||
; Stop processing on a NULL character.
|
||||
or eax,eax
|
||||
je short ??fini
|
||||
|
||||
; Special processing for a '\r' characters.
|
||||
cmp eax,CR
|
||||
je short ??cr
|
||||
|
||||
; Output character to monochrome monitor.
|
||||
??normal:
|
||||
; xor ah,ah
|
||||
|
||||
mov ebx,eax
|
||||
mov eax,[attrib]
|
||||
push eax
|
||||
push ebx
|
||||
call Mono_Put_Char
|
||||
add esp,8
|
||||
|
||||
; Perform adjustments if wrapping past right margin.
|
||||
cmp [WORD PTR MonoX],CPL
|
||||
jb short ??nowrap
|
||||
|
||||
inc [ypos]
|
||||
|
||||
mov eax,[ypos]
|
||||
push eax
|
||||
; sub eax,eax
|
||||
push 0
|
||||
call Mono_Set_Cursor
|
||||
add esp,8
|
||||
|
||||
jmp short ??nowrap
|
||||
|
||||
; Move to start of next line.
|
||||
??cr:
|
||||
inc [ypos]
|
||||
|
||||
mov eax,[ypos]
|
||||
push eax
|
||||
mov eax,[xpos]
|
||||
push eax
|
||||
call Mono_Set_Cursor
|
||||
add esp,8
|
||||
|
||||
; Scroll the monochrome screen if necessary.
|
||||
??nowrap:
|
||||
cmp [MonoY],LPS
|
||||
jb short ??noscroll
|
||||
|
||||
push 1
|
||||
call Mono_Scroll
|
||||
add esp,4
|
||||
|
||||
dec [ypos]
|
||||
|
||||
??noscroll:
|
||||
jmp short ??charloop
|
||||
|
||||
??fini:
|
||||
cmp [update],0
|
||||
jne short ??noupdate
|
||||
|
||||
call Mono_Set_Cursor
|
||||
??noupdate:
|
||||
add esp,8
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP _Mono_Text_Print
|
||||
|
||||
;=====================================================================
|
||||
|
||||
PROC Mono_Text_Print C near
|
||||
USES eax
|
||||
ARG text:DWORD
|
||||
ARG xpos:DWORD
|
||||
ARG ypos:DWORD
|
||||
ARG attrib:DWORD
|
||||
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; sub eax,eax
|
||||
push 0
|
||||
mov eax,[attrib]
|
||||
push eax
|
||||
mov eax,[ypos]
|
||||
push eax
|
||||
mov eax,[xpos]
|
||||
push eax
|
||||
mov eax,[text]
|
||||
push eax
|
||||
|
||||
call _Mono_Text_Print
|
||||
add esp,20
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Text_Print
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* MONO_PRINT -- Prints text to the mono screen at current pos. *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; void Mono_Print(void *text);
|
||||
|
||||
PROC Mono_Print C near
|
||||
|
||||
USES eax
|
||||
|
||||
ARG text:DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
; mov eax,1
|
||||
push 1
|
||||
; mov eax,2
|
||||
push 2
|
||||
mov eax,[MonoY]
|
||||
push eax
|
||||
mov eax,[MonoX]
|
||||
push eax
|
||||
mov eax,[text]
|
||||
push eax
|
||||
|
||||
call _Mono_Text_Print
|
||||
add esp,20
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Mono_Print
|
||||
|
||||
;***************************************************************************
|
||||
;* Mono_View_Page -- page in a mono screen *
|
||||
;* *
|
||||
;* Displays the specified page in displayable mono memory area. *
|
||||
;* *
|
||||
;* INPUT: WORD page = which page of memory we will use for storage *
|
||||
;* *
|
||||
;* OUTPUT: old_page *
|
||||
;* *
|
||||
;* WARNINGS: none. *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;*=========================================================================*
|
||||
; int cdecl Mono_View_Page(int page);
|
||||
|
||||
|
||||
PROC Mono_View_Page C near
|
||||
|
||||
USES eax,ebx,ecx,edx,edi,esi
|
||||
|
||||
ARG page:DWORD
|
||||
|
||||
LOCAL oldpage:DWORD
|
||||
|
||||
cmp [MonoEnabled],0
|
||||
je ??exit
|
||||
|
||||
cld
|
||||
|
||||
; mov ax,cs
|
||||
; and ax,7
|
||||
; or ax,SS_DATA
|
||||
|
||||
; mov ds,ax
|
||||
; mov es,ax
|
||||
|
||||
; Prepare the original page number for return to caller.
|
||||
mov ebx,[PageMap]
|
||||
mov [oldpage],ebx
|
||||
|
||||
; If the desired page is already displayed, then don't do anything.
|
||||
mov eax,[page]
|
||||
cmp eax,ebx
|
||||
je short ??fini
|
||||
|
||||
; Verify that page specified is legal.
|
||||
cmp eax,7
|
||||
ja short ??fini
|
||||
|
||||
; Find where the logical page to display is actually located.
|
||||
mov ecx,8
|
||||
|
||||
mov edi,OFFSET PageMap
|
||||
repne scasd
|
||||
neg ecx
|
||||
add ecx,7 ; ECX = where desired page is located.
|
||||
|
||||
; Swap the page ID bytes in the PageMap array.
|
||||
sub edi,4
|
||||
mov ebx,[PageMap]
|
||||
mov eax,[edi]
|
||||
mov [edi],ebx
|
||||
mov [PageMap],eax
|
||||
|
||||
; Set DS and ES to point to each page.
|
||||
; mov eax,[MonoScreen]
|
||||
; mov ds,ax
|
||||
mov esi , [ MonoScreen ]
|
||||
; shl ecx,8
|
||||
shl ecx , 12
|
||||
; add ecx,edi ; NO Addition to selectors!
|
||||
lea edi , [ esi + ecx ]
|
||||
|
||||
; mov edi,ecx
|
||||
; xor esi,esi
|
||||
|
||||
; Exchange the two pages.
|
||||
mov ecx,1000H/4
|
||||
|
||||
??looper:
|
||||
mov edx,[edi]
|
||||
mov ebx,[esi]
|
||||
mov [edi],ebx
|
||||
mov [esi],edx
|
||||
add esi,4
|
||||
add edi,4
|
||||
loop ??looper
|
||||
|
||||
; Return with the original page number.
|
||||
??fini:
|
||||
??exit:
|
||||
mov eax,[oldpage]
|
||||
ret
|
||||
|
||||
ENDP Mono_View_Page
|
||||
|
||||
END
|
||||
|
||||
789
WIN32LIB/SRCDEBUG/MONO.CPP
Normal file
789
WIN32LIB/SRCDEBUG/MONO.CPP
Normal file
@@ -0,0 +1,789 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Header: F:\projects\c&c\vcs\code\monoc.cpv 2.12 06 Sep 1995 16:37:54 JOE_BOSTIC $ */
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Command & Conquer *
|
||||
* *
|
||||
* File Name : MONO.CPP *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : July 2, 1994 *
|
||||
* *
|
||||
* Last Update : October 17, 1994 [JLB] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* MonoClass::Clear -- Clears the monochrome screen object. *
|
||||
* MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. *
|
||||
* MonoClass::MonoClass -- The default constructor for monochrome screen object. *
|
||||
* MonoClass::operator = -- Handles making one mono object have the same imagery as another. *
|
||||
* MonoClass::Print -- Prints the text string at the current cursor coordinates. *
|
||||
* MonoClass::Printf -- Prints a formatted string to the monochrome screen. *
|
||||
* MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. *
|
||||
* MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. *
|
||||
* MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. *
|
||||
* MonoClass::View -- Brings the mono object to the main display. *
|
||||
* MonoClass::~MonoClass -- The default destructor for a monochrome screen object. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//#pragma inline
|
||||
#include "mono.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dos.h>
|
||||
#include <mem.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
extern void output(short port, short data);
|
||||
#pragma aux output parm [dx] [ax] = \
|
||||
"out dx,al" \
|
||||
"inc dx" \
|
||||
"mov al,ah" \
|
||||
"out dx,al"
|
||||
|
||||
int MonoClass::Enabled = 0;
|
||||
MonoClass * MonoClass::PageUsage[MonoClass::MAX_MONO_PAGES] = {0,0,0,0,0,0,0,0};
|
||||
void * MonoClass::MonoSegment = (void*)0x000b0000;
|
||||
|
||||
/*
|
||||
** These are the IBM linedraw characters.
|
||||
*/
|
||||
MonoClass::BoxDataType const MonoClass::CharData[MonoClass::COUNT] = {
|
||||
{0xDA,0xC4,0xBF,0xB3,0xD9,0xC4,0xC0,0xB3}, // Single line
|
||||
{0xD5,0xCD,0xB8,0xB3,0xBE,0xCD,0xD4,0xB3}, // Double horz.
|
||||
{0xD6,0xC4,0xB7,0xBA,0xBD,0xC4,0xD3,0xBA}, // Double vert.
|
||||
{0xC9,0xCD,0xBB,0xBA,0xBC,0xCD,0xC8,0xBA} // Double horz and vert.
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::MonoClass -- The default constructor for monochrome screen object. *
|
||||
* *
|
||||
* This is the constructor for monochrome screen objects. It handles allocating a free *
|
||||
* monochrome page. If there are no more pages available, then this is a big error. The *
|
||||
* page allocated may not be the visible one. Call the View function in order to bring *
|
||||
* it to the displayed page. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
MonoClass::MonoClass(void)
|
||||
{
|
||||
int index;
|
||||
|
||||
Attrib = DEFAULT_ATTRIBUTE; // Normal text color.
|
||||
X = Y = 0;
|
||||
for (index = 0; index < MAX_MONO_PAGES; index++) {
|
||||
if (!PageUsage[index]) {
|
||||
PageUsage[index] = this;
|
||||
Page = (char)index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == MAX_MONO_PAGES) {
|
||||
// Major error message should pop up here!
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::~MonoClass -- The default destructor for a monochrome screen object. *
|
||||
* *
|
||||
* This is the default destructor for a monochrome screen object. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
MonoClass::~MonoClass(void)
|
||||
{
|
||||
PageUsage[Page] = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. *
|
||||
* *
|
||||
* Use this routine to draw a box to the monochrome screen. The IBM line draw characters *
|
||||
* are used to give the it a fancy appearance. There are several line draw modes supported. *
|
||||
* *
|
||||
* INPUT: x,y -- The coordinates of the upper left corner of the box. *
|
||||
* *
|
||||
* w,y -- The width and height (respectively) to make the box. *
|
||||
* *
|
||||
* attrib -- The text attribute to use when drawing the box outline characters. *
|
||||
* *
|
||||
* thick -- The thickness style to use. Examine the BoxStyleType enum for *
|
||||
* elaboration on the supported styles. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: The interior of the box is NOT cleared by this routine. It is advised that this *
|
||||
* area be cleared before the box is drawn. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Draw_Box(int x, int y, int w, int h, char attrib, BoxStyleType thick)
|
||||
{
|
||||
CellType cell;
|
||||
char oldattrib = Attrib;
|
||||
|
||||
if (!Enabled || !w || !h) return;
|
||||
|
||||
cell.Attribute = attrib;
|
||||
|
||||
/*
|
||||
** Draw the horizontal lines.
|
||||
*/
|
||||
for (int xpos = 0; xpos < w-2; xpos++) {
|
||||
cell.Character = CharData[thick].TopEdge;
|
||||
Store_Cell(cell, x+xpos+1, y);
|
||||
cell.Character = CharData[thick].BottomEdge;
|
||||
Store_Cell(cell, x+xpos+1, y+h-1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Draw the vertical lines.
|
||||
*/
|
||||
for (int ypos = 0; ypos < h-2; ypos++) {
|
||||
cell.Character = CharData[thick].LeftEdge;
|
||||
Store_Cell(cell, x, y+ypos+1);
|
||||
cell.Character = CharData[thick].RightEdge;
|
||||
Store_Cell(cell, x+w-1, y+ypos+1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Draw the four corners.
|
||||
*/
|
||||
if (w > 1 && h > 1) {
|
||||
cell.Character = CharData[thick].UpperLeft;
|
||||
Store_Cell(cell, x, y);
|
||||
cell.Character = CharData[thick].UpperRight;
|
||||
Store_Cell(cell, x+w-1, y);
|
||||
cell.Character = CharData[thick].BottomRight;
|
||||
Store_Cell(cell, x+w-1, y+h-1);
|
||||
cell.Character = CharData[thick].BottomLeft;
|
||||
Store_Cell(cell, x, y+h-1);
|
||||
}
|
||||
|
||||
Attrib = oldattrib;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. *
|
||||
* *
|
||||
* Use this routine to set the monochrome's cursor position to the coordinates specified. *
|
||||
* This is the normal way of controlling where the next Print or Printf will output the *
|
||||
* text to. *
|
||||
* *
|
||||
* INPUT: x,y -- The coordinate to position the monochrome cursor. 0,0 is the upper left *
|
||||
* corner. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Set_Cursor(int x, int y)
|
||||
{
|
||||
#if(0)
|
||||
int pos = (y*COLUMNS)+x;
|
||||
|
||||
if (!Enabled) return;
|
||||
|
||||
X = (char)(x%COLUMNS);
|
||||
Y = (char)(y%LINES);
|
||||
|
||||
if (Page == 0) {
|
||||
_DX = CONTROL_PORT;
|
||||
_AX = (short)(0x0E|(pos&0xFF00));
|
||||
asm {
|
||||
out dx,al
|
||||
inc dx
|
||||
mov al,ah
|
||||
out dx,al
|
||||
}
|
||||
|
||||
_DX = CONTROL_PORT;
|
||||
_AX = (short)(0x0F|(pos<<8));
|
||||
asm {
|
||||
out dx,al
|
||||
inc dx
|
||||
mov al,ah
|
||||
out dx,al
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
int pos = (y*COLUMNS)+x;
|
||||
|
||||
if (!Enabled) return;
|
||||
|
||||
X = (char)(x%COLUMNS);
|
||||
Y = (char)(y%LINES);
|
||||
|
||||
if (Page == 0) {
|
||||
output(CONTROL_PORT,
|
||||
(short)0x0E|(short)(pos&0xFF00));
|
||||
output(CONTROL_PORT,
|
||||
(short)0x0F|(short)(pos<<8));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Clear -- Clears the monochrome screen object. *
|
||||
* *
|
||||
* This routine will fill the monochrome screen object with spaces. It is clearing the *
|
||||
* screen of data, making it free for output. The cursor is positioned at the upper left *
|
||||
* corner of the screen by this routine. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Clear(void)
|
||||
{
|
||||
CellType cell;
|
||||
|
||||
if (!Enabled) return;
|
||||
|
||||
Set_Cursor(0, 0);
|
||||
|
||||
cell.Attribute = Attrib;
|
||||
cell.Character = ' ';
|
||||
|
||||
for (int y = 0; y < LINES; y++) {
|
||||
for (int x = 0; x < COLUMNS; x++) {
|
||||
Store_Cell(cell, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. *
|
||||
* *
|
||||
* Use this routine to scroll the monochrome screen up by the number of lines specified. *
|
||||
* This routine is typically called by the printing functions so that the monochrome screen *
|
||||
* behaves in the expected manner -- printing at the bottom of the screen scrolls it up *
|
||||
* to make room for new text. *
|
||||
* *
|
||||
* INPUT: lines -- The number of lines to scroll the monochrome screen. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Scroll(int lines)
|
||||
{
|
||||
CellType cell;
|
||||
|
||||
if (!Enabled || lines <= 0) return;
|
||||
|
||||
memmove( (void*)((long)MonoSegment + Offset(0, 0)),
|
||||
(void*)((long)MonoSegment + Offset(0, lines)),
|
||||
(LINES-lines)*COLUMNS*sizeof(CellType));
|
||||
|
||||
|
||||
Y--;
|
||||
cell.Attribute = Attrib;
|
||||
cell.Character = ' ';
|
||||
|
||||
for (int l = LINES-lines; l < LINES; l++) {
|
||||
for (int index = 0; index < COLUMNS; index++) {
|
||||
Store_Cell(cell, index, l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Printf -- Prints a formatted string to the monochrome screen. *
|
||||
* *
|
||||
* Use this routine to output a formatted string, using the standard formatting options, *
|
||||
* to the monochrome screen object's current cursor position. *
|
||||
* *
|
||||
* INPUT: text -- Pointer to the text to print. *
|
||||
* *
|
||||
* ... -- Any optional parameters to supply in formatting the text. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: The total formatted text length must not exceed 255 characters. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Printf(char const *text, ...)
|
||||
{
|
||||
va_list va;
|
||||
/*
|
||||
** The buffer object is placed at the end of the local variable list
|
||||
** so that if the sprintf happens to spill past the end, it isn't likely
|
||||
** to trash anything (important). The buffer is then manually truncated
|
||||
** to maximum allowed size before being printed.
|
||||
*/
|
||||
char buffer[256];
|
||||
|
||||
if (!Enabled) return;
|
||||
|
||||
va_start(va, text);
|
||||
vsprintf(buffer, text, va);
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
|
||||
Print(buffer);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
|
||||
#ifdef NEVER
|
||||
void MonoClass::Printf(int text, ...)
|
||||
{
|
||||
va_list va;
|
||||
/*
|
||||
** The buffer object is placed at the end of the local variable list
|
||||
** so that if the sprintf happens to spill past the end, it isn't likely
|
||||
** to trash anything (important). The buffer is then manually truncated
|
||||
** to maximum allowed size before being printed.
|
||||
*/
|
||||
char buffer[256];
|
||||
|
||||
if (!Enabled) return;
|
||||
|
||||
va_start(va, text);
|
||||
vsprintf(buffer, Text_String(text), va);
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
|
||||
Print(buffer);
|
||||
va_end(va);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Print -- Prints the text string at the current cursor coordinates. *
|
||||
* *
|
||||
* Use this routine to output the specified text string at the monochrome object's current *
|
||||
* text coordinate position. *
|
||||
* *
|
||||
* INPUT: ptr -- Pointer to the string to print. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Print(char const *ptr)
|
||||
{
|
||||
char startcol = X;
|
||||
char const * text;
|
||||
CellType cell;
|
||||
|
||||
if (!ptr || !Enabled) return;
|
||||
|
||||
text = ptr;
|
||||
cell.Attribute = Attrib;
|
||||
while (*text) {
|
||||
|
||||
/*
|
||||
** Sometimes the character string is used for cursor control instead
|
||||
** of plain text output. Check for this case.
|
||||
*/
|
||||
switch (*text) {
|
||||
|
||||
/*
|
||||
** The "return" code behaves as it did in the old C library
|
||||
** mono system. That is, it returns the cursor position to
|
||||
** the next line but at the starting column of the print.
|
||||
*/
|
||||
case '\r':
|
||||
X = startcol;
|
||||
Y++;
|
||||
Scroll(Y-(LINES-1));
|
||||
break;
|
||||
|
||||
/*
|
||||
** The "newline" code behaves like the console newline character.
|
||||
** That is, it moves the cursor down one line and at the first
|
||||
** column.
|
||||
*/
|
||||
case '\n':
|
||||
X = 0;
|
||||
Y++;
|
||||
Scroll(Y-(LINES-1));
|
||||
break;
|
||||
|
||||
/*
|
||||
** All other characters are output directly and the cursor moves
|
||||
** rightward to match. If the cursor wraps past the right
|
||||
** edge is it moved to the next now down at left margin. If the
|
||||
** cursor goes off the bottom of the display, the display is scrolled
|
||||
** upward a line.
|
||||
*/
|
||||
default:
|
||||
cell.Character = *text;
|
||||
Store_Cell(cell, X, Y);
|
||||
|
||||
X++;
|
||||
if (X >= COLUMNS) {
|
||||
X = 0;
|
||||
Y++;
|
||||
|
||||
if (Y > (LINES-1)) {
|
||||
Scroll(Y-(LINES-1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
text++;
|
||||
}
|
||||
|
||||
Set_Cursor(X, Y);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. *
|
||||
* *
|
||||
* Use this routine to output text to the monochrome object at the X and Y coordinates *
|
||||
* specified. *
|
||||
* *
|
||||
* INPUT: text -- Pointer to the text string to display. *
|
||||
* *
|
||||
* x,y -- The X and Y character coordinates to start the printing at. *
|
||||
* *
|
||||
* attrib-- Optional parameter that specifies what text attribute code to use. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::Text_Print(char const *text, int x, int y, char attrib)
|
||||
{
|
||||
char oldx = X;
|
||||
char oldy = Y;
|
||||
char oldattrib = Attrib;
|
||||
|
||||
X = (char)x;
|
||||
Y = (char)y;
|
||||
Attrib = attrib;
|
||||
Print(text);
|
||||
Attrib = oldattrib;
|
||||
Set_Cursor(oldx, oldy);
|
||||
}
|
||||
|
||||
#ifdef NEVER
|
||||
void MonoClass::Text_Print(int text, int x, int y, char attrib)
|
||||
{
|
||||
char oldx = X;
|
||||
char oldy = Y;
|
||||
char oldattrib = Attrib;
|
||||
|
||||
if (text != TXT_NONE) {
|
||||
X = (char)x;
|
||||
Y = (char)y;
|
||||
Attrib = attrib;
|
||||
Print(Text_String(text));
|
||||
Attrib = oldattrib;
|
||||
Set_Cursor(oldx, oldy);
|
||||
}
|
||||
}
|
||||
|
||||
void MonoClass::Print(int text)
|
||||
{
|
||||
Print(Text_String(text));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::operator = -- Handles making one mono object have the same imagery as another. *
|
||||
* *
|
||||
* The assignment operator will handle copying the imagery from one monochrome object to *
|
||||
* another. Use this routine in to make two monochrome class objects visually identical. *
|
||||
* *
|
||||
* INPUT: src -- A reference to the source (right side) monochrome object. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
MonoClass & MonoClass::operator = (MonoClass const & src)
|
||||
{
|
||||
memcpy((void*)((long)MonoSegment + src.Offset(0, 0)), (void*)((long)MonoSegment + Offset(0, 0)), SIZE_OF_PAGE);
|
||||
Set_Cursor(src.X, src.Y);
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MonoClass::View -- Brings the mono object to the main display. *
|
||||
* *
|
||||
* Use this routine to display the mono object on the monochrome screen. It is possible *
|
||||
* that the mono object exists on some background screen memory. Calling this routine will *
|
||||
* perform the necessary memory swapping to bring the data to the front. The mono object *
|
||||
* that was currently being viewed is not destroyed by this function. It is merely moved *
|
||||
* off to some background page. It can be treated normally, except that is just isn't *
|
||||
* visible. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void MonoClass::View(void)
|
||||
{
|
||||
MonoClass *displace; // The page that is being displaced.
|
||||
|
||||
if (Get_Current() == this) return;
|
||||
|
||||
/*
|
||||
** If the visible page is already assigned to a real monochrome page
|
||||
** object, then it must be swapped with the new one.
|
||||
*/
|
||||
displace = Get_Current();
|
||||
if (displace) {
|
||||
char temp[SIZE_OF_PAGE];
|
||||
|
||||
memcpy(&temp[0], MonoSegment, SIZE_OF_PAGE);
|
||||
memcpy(MonoSegment, (void*)((long)MonoSegment + Offset(0, 0)), SIZE_OF_PAGE);
|
||||
memcpy((void*)((long)MonoSegment + Offset(0, 0)), &temp[0], SIZE_OF_PAGE);
|
||||
|
||||
displace->Page = Page;
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Just copy the new page over since the display page is not assigned
|
||||
** to a real monochrome page object.
|
||||
*/
|
||||
memcpy(MonoSegment, (void*)((long)MonoSegment + Offset(0, 0)), SIZE_OF_PAGE);
|
||||
}
|
||||
PageUsage[Page] = displace;
|
||||
PageUsage[0] = this;
|
||||
Page = 0;
|
||||
|
||||
Set_Cursor(X, Y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
** This is the set of C wrapper functions that access the MonoClass support routines.
|
||||
** Since the C interface doesn't have the ability to write to non-visible pages, it
|
||||
** will just blast the output to whichever mono page is currently visible. If there is
|
||||
** no mono class object that is visible, then one will be created -- BUT NOT FREED.
|
||||
** Typically, this is ok, since the C interface will create only one MonoClass object
|
||||
** and the system supports up to 8.
|
||||
*/
|
||||
void Mono_Set_Cursor(int x, int y)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
mono->Set_Cursor(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
int Mono_Printf(char const *string, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buffer[256];
|
||||
|
||||
buffer[0] = '\0';
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
|
||||
va_start(va, string);
|
||||
vsprintf(buffer, string, va);
|
||||
|
||||
mono->Print(buffer);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
return((short)strlen(buffer));
|
||||
}
|
||||
|
||||
|
||||
void Mono_Clear_Screen(void)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
mono->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Mono_Text_Print(void const *text, int x, int y, int attrib)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
mono->Text_Print((const char*)text, x, y, (char)attrib);
|
||||
}
|
||||
}
|
||||
|
||||
void Mono_Draw_Rect(int x, int y, int w, int h, int attrib, int thick)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
mono->Draw_Box(x, y, w, h, (char)attrib, (MonoClass::BoxStyleType)thick);
|
||||
}
|
||||
}
|
||||
|
||||
void Mono_Print(void const *text)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
mono->Print((const char*)text);
|
||||
}
|
||||
}
|
||||
|
||||
int Mono_X(void)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
return(short)mono->Get_X();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int Mono_Y(void)
|
||||
{
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
return(short)mono->Get_X();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void Mono_Put_Char(char , int )
|
||||
{
|
||||
}
|
||||
|
||||
void Mono_Scroll(int )
|
||||
{
|
||||
}
|
||||
|
||||
void Mono_View_Page(int )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifdef NEVER
|
||||
int Mono_Printf(int string, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buffer[256];
|
||||
|
||||
buffer[0] = '\0';
|
||||
if (MonoClass::Is_Enabled()) {
|
||||
MonoClass *mono = MonoClass::Get_Current();
|
||||
if (!mono) {
|
||||
mono = new MonoClass();
|
||||
mono->View();
|
||||
}
|
||||
|
||||
va_start(va, string);
|
||||
vsprintf(buffer, Text_String(string), va);
|
||||
|
||||
mono->Print(buffer);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
return((short)strlen(buffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
77
WIN32LIB/SRCDEBUG/MONOPRNT.CPP
Normal file
77
WIN32LIB/SRCDEBUG/MONOPRNT.CPP
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : MONOPRNT.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : October 12, 1993 *
|
||||
* *
|
||||
* Last Update : November 2, 1993 [JLB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Mono_Printf -- Prints formated text to the monochrome screen. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "mono.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Mono_Printf -- Prints formated text to the monochrome screen. *
|
||||
* *
|
||||
* This routine is used to print formatted text (similar to printf) to *
|
||||
* the monochrome screen. *
|
||||
* *
|
||||
* INPUT: string -- The string that is to be printed. *
|
||||
* *
|
||||
* ... -- Any optional parameters that the string requires *
|
||||
* to format properly. *
|
||||
* *
|
||||
* OUTPUT: Returns with the length of the string that it printed to the *
|
||||
* monochrome screen. *
|
||||
* *
|
||||
* WARNINGS: The total length of the formatted string must not exceed *
|
||||
* 255 bytes. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/02/1993 JLB : Created. *
|
||||
*=========================================================================*/
|
||||
int Mono_Printf(char const *string, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buffer[256];
|
||||
|
||||
if (!MonoEnabled) return(0);
|
||||
|
||||
va_start(va, string);
|
||||
|
||||
vsprintf(buffer, string, va);
|
||||
Mono_Print(buffer);
|
||||
|
||||
va_end(va);
|
||||
return(strlen(buffer));
|
||||
}
|
||||
176
WIN32LIB/SRCDEBUG/MORPHPAL.CPP
Normal file
176
WIN32LIB/SRCDEBUG/MORPHPAL.CPP
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : wwlib32 *
|
||||
* *
|
||||
* File Name : PALTOPAL.CPP *
|
||||
* *
|
||||
* Programmer : Bill Randolph *
|
||||
* *
|
||||
* Start Date : May 2, 1994 *
|
||||
* *
|
||||
* Last Update : May 2, 1994 [BR] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Morph_Palette -- morphs a palette from source to destination *
|
||||
* Palette_To_Palette -- morph src palette to a dst palette *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/*
|
||||
********************************* Includes **********************************
|
||||
*/
|
||||
#include "wwstd.h"
|
||||
#include "palette.h"
|
||||
#include "timer.h"
|
||||
|
||||
/*
|
||||
********************************* Constants *********************************
|
||||
*/
|
||||
#define SCALE(a,b,c) (((((long)(a)<<8) / (long)(b) ) * (unsigned long)(c)) >>8)
|
||||
|
||||
|
||||
/*
|
||||
********************************** Globals **********************************
|
||||
*/
|
||||
|
||||
/*
|
||||
******************************** Prototypes *********************************
|
||||
*/
|
||||
|
||||
PRIVATE int __cdecl Palette_To_Palette(void *src_palette, void *dst_palette, unsigned long current_time, unsigned long delay);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Morph_Palette -- morphs a palette from source to destination *
|
||||
* *
|
||||
* INPUT: *
|
||||
* void *src_pal - starting palette *
|
||||
* void *dst_pal - ending palette *
|
||||
* unsigned int delay - time delay in 60ths of a second *
|
||||
* void *callback - user-defined callback, NULL if none *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* none. *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/02/1994 BR : Created. *
|
||||
*=========================================================================*/
|
||||
void cdecl Morph_Palette (void *src_pal, void *dst_pal, unsigned int delay,
|
||||
void (*callback) (void) )
|
||||
{
|
||||
int result;
|
||||
unsigned long pal_start = TickCount.Time();
|
||||
extern void (*cb_ptr) ( void ) ; // callback function pointer
|
||||
|
||||
// (void *)cb_ptr = callback;
|
||||
cb_ptr = callback ;
|
||||
|
||||
/*===================================================================*/
|
||||
/* Make sure that we don't go too fast but also make sure we keep */
|
||||
/* processing the morph palette if we have one. */
|
||||
/*===================================================================*/
|
||||
while (1) {
|
||||
if (src_pal && dst_pal) {
|
||||
result = Palette_To_Palette (src_pal, dst_pal,
|
||||
(TickCount.Time() - pal_start), (unsigned long)delay);
|
||||
if (!result)
|
||||
break;
|
||||
|
||||
if (callback) {
|
||||
(*cb_ptr)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} /* end of Morph_Palette */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Palette_To_Palette -- morph src palette to a dst palette *
|
||||
* *
|
||||
* Creates & sets a palette that's in-between 'src_palette' & *
|
||||
* 'dst_palette'; how close it is to dst_palette is based on how close *
|
||||
* 'current_time' is to 'delay'. 'current_time' & 'delay' are based on *
|
||||
* 0 being the start time. *
|
||||
* *
|
||||
* INPUT: void *src_palette = palette we want to morph from *
|
||||
* void *dst_palette = palette we want to morph to *
|
||||
* long current_time = time we started morph pal *
|
||||
* long delay = time we want the morph to take*
|
||||
* *
|
||||
* OUTPUT: int if the time had elapsed and no chages were *
|
||||
* necessary this routine returns FALSE *
|
||||
* otherwise it will always return TRUE (this *
|
||||
* was necessary to detect the end of the ice *
|
||||
* effect. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/24/1993 MC : Created. *
|
||||
*=========================================================================*/
|
||||
PRIVATE int cdecl Palette_To_Palette(void *src_palette, void *dst_palette,
|
||||
unsigned long current_time, unsigned long delay)
|
||||
{
|
||||
char colour;
|
||||
char diff;
|
||||
int chgval;
|
||||
int lp;
|
||||
int change;
|
||||
static char palette[768];
|
||||
char *src_pal = (char*)src_palette;
|
||||
char *dst_pal = (char*)dst_palette;
|
||||
|
||||
/*======================================================================*/
|
||||
/* Loop through each RGB value attempting to change it to the correct */
|
||||
/* color. */
|
||||
/*======================================================================*/
|
||||
for (change = lp = 0; lp < 768; lp++) {
|
||||
if (current_time < delay ) {
|
||||
diff = dst_pal[lp] & (char)63;
|
||||
diff -= src_pal[lp] & (char)63;
|
||||
if (diff)
|
||||
change = TRUE;
|
||||
chgval = SCALE(diff, delay, current_time);
|
||||
colour = src_pal[lp] & (char)63;
|
||||
colour +=(char)chgval;
|
||||
}
|
||||
else {
|
||||
colour = dst_pal[lp] & (char)63;
|
||||
change = FALSE;
|
||||
}
|
||||
palette[lp] = colour;
|
||||
}
|
||||
/*======================================================================*/
|
||||
/* Set the palette to the color that we created. */
|
||||
/*======================================================================*/
|
||||
Set_Palette(palette);
|
||||
return(change);
|
||||
|
||||
} /* end of Palette_To_Palette */
|
||||
|
||||
|
||||
/*************************** End of morphpal.cpp ***************************/
|
||||
|
||||
|
||||
2246
WIN32LIB/SRCDEBUG/MOUSE.ASM
Normal file
2246
WIN32LIB/SRCDEBUG/MOUSE.ASM
Normal file
File diff suppressed because it is too large
Load Diff
673
WIN32LIB/SRCDEBUG/MOUSE.CPP
Normal file
673
WIN32LIB/SRCDEBUG/MOUSE.CPP
Normal file
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 32 bit Library *
|
||||
* *
|
||||
* File Name : MOUSE.CPP *
|
||||
* *
|
||||
* Programmer : Philip W. Gorrow *
|
||||
* *
|
||||
* Start Date : 12/12/95 *
|
||||
* *
|
||||
* Last Update : December 12, 1995 [PWG] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* WWMouseClass::WWMouseClass -- Constructor for the Mouse Class *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "mouse.h"
|
||||
#include <mmsystem.h>
|
||||
|
||||
static WWMouseClass *_Mouse=NULL;
|
||||
void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 );
|
||||
extern BOOL GameInFocus;
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MOUSECLASS::MOUSECLASS -- Constructor for the Mouse Class *
|
||||
* *
|
||||
* INPUT: GraphicViewPortClass * screen - pointer to screen mouse is created for *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/12/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
WWMouseClass::WWMouseClass(GraphicViewPortClass *scr, int mouse_max_width, int mouse_max_height)
|
||||
{
|
||||
MouseCursor = new char[mouse_max_width * mouse_max_height];
|
||||
MouseXHot = 0;
|
||||
MouseYHot = 0;
|
||||
CursorWidth = 0;
|
||||
CursorHeight = 0;
|
||||
|
||||
MouseBuffer = new char[mouse_max_width * mouse_max_height];
|
||||
MouseBuffX = -1;
|
||||
MouseBuffY = -1;
|
||||
MaxWidth = mouse_max_width;
|
||||
MaxHeight = mouse_max_height;
|
||||
|
||||
MouseCXLeft = 0;
|
||||
MouseCYUpper = 0;
|
||||
MouseCXRight = 0;
|
||||
MouseCYLower = 0;
|
||||
MCFlags = 0;
|
||||
MCCount = 0;
|
||||
|
||||
Screen = scr;
|
||||
PrevCursor = NULL;
|
||||
MouseUpdate = 0;
|
||||
State = 1;
|
||||
timeBeginPeriod ( 1000/ 60);
|
||||
|
||||
InitializeCriticalSection (&MouseCriticalSection);
|
||||
//
|
||||
// Install the timer callback event handler
|
||||
//
|
||||
|
||||
EraseBuffer = new char[mouse_max_width * mouse_max_height];
|
||||
EraseBuffX = -1;
|
||||
EraseBuffY = -1;
|
||||
EraseBuffHotX = -1;
|
||||
EraseBuffHotY = -1;
|
||||
EraseFlags = FALSE;
|
||||
|
||||
_Mouse = this;
|
||||
TimerHandle = timeSetEvent( 1000/60 , 1 , ::Process_Mouse, 0 , TIME_PERIODIC);
|
||||
|
||||
/*
|
||||
** Force the windows mouse pointer to stay withing the graphic view port region
|
||||
*/
|
||||
Set_Cursor_Clip();
|
||||
}
|
||||
|
||||
WWMouseClass::~WWMouseClass()
|
||||
{
|
||||
MouseUpdate++;
|
||||
|
||||
if (MouseCursor) delete[] MouseCursor;
|
||||
if (MouseBuffer) delete[] MouseBuffer;
|
||||
if (TimerHandle) {
|
||||
timeKillEvent(TimerHandle);
|
||||
}
|
||||
timeEndPeriod (1000/60);
|
||||
DeleteCriticalSection(&MouseCriticalSection);
|
||||
|
||||
/*
|
||||
** Free up the windows mouse pointer movement
|
||||
*/
|
||||
Clear_Cursor_Clip();
|
||||
}
|
||||
|
||||
|
||||
void Block_Mouse(GraphicBufferClass *buffer)
|
||||
{
|
||||
if (_Mouse){
|
||||
_Mouse->Block_Mouse(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Unblock_Mouse(GraphicBufferClass *buffer)
|
||||
{
|
||||
if (_Mouse){
|
||||
_Mouse->Unblock_Mouse(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WWMouseClass::Block_Mouse(GraphicBufferClass *buffer)
|
||||
{
|
||||
if (buffer == Screen->Get_Graphic_Buffer()){
|
||||
EnterCriticalSection(&MouseCriticalSection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WWMouseClass::Unblock_Mouse(GraphicBufferClass *buffer)
|
||||
{
|
||||
if (buffer == Screen->Get_Graphic_Buffer()){
|
||||
LeaveCriticalSection(&MouseCriticalSection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void WWMouseClass::Set_Cursor_Clip(void)
|
||||
{
|
||||
|
||||
if (Screen){
|
||||
RECT region;
|
||||
|
||||
region.left = 0;
|
||||
region.top = 0;
|
||||
region.right = Screen->Get_Width();
|
||||
region.bottom = Screen->Get_Height();
|
||||
|
||||
ClipCursor(®ion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WWMouseClass::Clear_Cursor_Clip(void)
|
||||
{
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WWMouseClass::Process_Mouse(void)
|
||||
{
|
||||
POINT pt; // define a structure to hold current cursor pos
|
||||
|
||||
//
|
||||
// If the mouse is currently hidden or it has not been installed, then we
|
||||
// have no need to redraw the mouse.
|
||||
//
|
||||
if (!Screen || !_Mouse || State > 0 || MouseUpdate || EraseFlags || !GameInFocus)
|
||||
return;
|
||||
|
||||
//
|
||||
// Make sure there are no conflicts with other
|
||||
// threads that may try and lock the screen buffer
|
||||
//
|
||||
//Block_Mouse(Screen->Get_Graphic_Buffer());
|
||||
|
||||
//
|
||||
// If the screen is already locked by another thread then just exit
|
||||
//
|
||||
if (Screen->Get_LockCount()!=0){
|
||||
//Unblock_Mouse(Screen->Get_Graphic_Buffer());
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the mouse's current real cursor position
|
||||
//
|
||||
GetCursorPos(&pt); // get the current cursor position
|
||||
//
|
||||
// If the mouse has moved then we are responsible to redraw the mouse
|
||||
//
|
||||
if (pt.x != MouseBuffX || pt.y != MouseBuffY) {
|
||||
//
|
||||
// If we can't lock the surface we need to draw to, we cannot update
|
||||
// the mouse.
|
||||
//
|
||||
if (Screen->Lock()) {
|
||||
//
|
||||
// Erase the old mouse by dumping the mouses shadow buff
|
||||
// to the screen (if its position had ever been recorded).
|
||||
//
|
||||
Low_Hide_Mouse();
|
||||
|
||||
//
|
||||
// Verify that the mouse has not gone into a conditional hiden area
|
||||
// If it has, mark it as being in one.
|
||||
//
|
||||
if (MCFlags & CONDHIDE && pt.x >= MouseCXLeft && pt.x <= MouseCXRight && pt.y >= MouseCYUpper && pt.y <= MouseCYLower) {
|
||||
MCFlags |= CONDHIDDEN;
|
||||
}
|
||||
|
||||
//
|
||||
// Show the mouse if we are allowed to.
|
||||
//
|
||||
if (!(MCFlags & CONDHIDDEN)) {
|
||||
Low_Show_Mouse(pt.x, pt.y);
|
||||
}
|
||||
//
|
||||
// Finally unlock the destination surface as we have sucessfully
|
||||
// updated the mouse.
|
||||
//
|
||||
Screen->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Allow other threads to lock the screen again
|
||||
//
|
||||
//Unblock_Mouse(Screen->Get_Graphic_Buffer());
|
||||
}
|
||||
|
||||
void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor)
|
||||
{
|
||||
//
|
||||
// If the pointer to the cursor we got is invalid, or its the same as the
|
||||
// currently set cursor then just return.
|
||||
if (!cursor || cursor == PrevCursor)
|
||||
return(cursor);
|
||||
|
||||
//
|
||||
// Wait until we have exclusive access to our data
|
||||
//
|
||||
MouseUpdate++;
|
||||
//
|
||||
// Since we are updating the mouse we need to hide the cursor so we
|
||||
// do not get some sort of weird transformation.
|
||||
//
|
||||
Hide_Mouse();
|
||||
//
|
||||
// Now convert the shape to a mouse cursor with the given hotspots and
|
||||
// set it as our current mouse.
|
||||
//
|
||||
void *retval = ASM_Set_Mouse_Cursor(this, xhotspot, yhotspot, cursor);
|
||||
//
|
||||
// Show the mouse which will force it to appear with the new shape we
|
||||
// have assigned.
|
||||
//
|
||||
Show_Mouse();
|
||||
//
|
||||
// We are done updating the mouse cursor so on to bigger and better things.
|
||||
//
|
||||
MouseUpdate--;
|
||||
//
|
||||
// Return the previous mouse cursor which as conveniantly passed back by
|
||||
// Asm_Set_Mouse_Cursor.
|
||||
//
|
||||
return(retval);
|
||||
}
|
||||
|
||||
void WWMouseClass::Low_Hide_Mouse()
|
||||
{
|
||||
if (!State) {
|
||||
if (MouseBuffX != -1 || MouseBuffY != -1) {
|
||||
if (Screen->Lock()){
|
||||
Mouse_Shadow_Buffer(this, Screen, MouseBuffer, MouseBuffX, MouseBuffY, MouseXHot, MouseYHot, 0);
|
||||
Screen->Unlock();
|
||||
}
|
||||
}
|
||||
MouseBuffX = -1;
|
||||
MouseBuffY = -1;
|
||||
}
|
||||
State++;
|
||||
}
|
||||
void WWMouseClass::Hide_Mouse()
|
||||
{
|
||||
MouseUpdate++;
|
||||
Low_Hide_Mouse();
|
||||
MouseUpdate--;
|
||||
}
|
||||
|
||||
|
||||
void WWMouseClass::Low_Show_Mouse(int x, int y)
|
||||
{
|
||||
//
|
||||
// If the mouse is already visible then just ignore the problem.
|
||||
//
|
||||
if (State == 0) return;
|
||||
//
|
||||
// Make the mouse a little bit more visible
|
||||
//
|
||||
State--;
|
||||
|
||||
//
|
||||
// If the mouse is completely visible then draw it at its current
|
||||
// position.
|
||||
//
|
||||
if (!State) {
|
||||
//
|
||||
// Try to lock the screen til we sucessfully get a lock.
|
||||
//
|
||||
if (Screen->Lock()){
|
||||
//
|
||||
// Save off the area behind the mouse.
|
||||
//
|
||||
Mouse_Shadow_Buffer(this, Screen, MouseBuffer, x, y, MouseXHot, MouseYHot, 1);
|
||||
//
|
||||
// Draw the mouse in its new location
|
||||
//
|
||||
::Draw_Mouse(this, Screen, x, y);
|
||||
//
|
||||
// Save off the positions that we saved the buffer from
|
||||
//
|
||||
MouseBuffX = x;
|
||||
MouseBuffY = y;
|
||||
//
|
||||
// Unlock the screen and lets get moving.
|
||||
//
|
||||
Screen->Unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WWMouseClass::Show_Mouse()
|
||||
{
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
|
||||
MouseUpdate++;
|
||||
Low_Show_Mouse(pt.x, pt.y);
|
||||
MouseUpdate--;
|
||||
}
|
||||
|
||||
void WWMouseClass::Conditional_Hide_Mouse(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
MouseUpdate++;
|
||||
|
||||
//
|
||||
// First of all, adjust all the coordinates so that they handle
|
||||
// the fact that the hotspot is not necessarily the upper left
|
||||
// corner of the mouse.
|
||||
//
|
||||
x1 -= (CursorWidth - MouseXHot);
|
||||
x1 = MAX(0, x1);
|
||||
y1 -= (CursorHeight - MouseYHot);
|
||||
y1 = MAX(0, y1);
|
||||
x2 += MouseXHot;
|
||||
x2 = MIN(x2, Screen->Get_Width());
|
||||
y2 += MouseYHot;
|
||||
y2 = MIN(y2, Screen->Get_Height());
|
||||
|
||||
// The mouse could be in one of four conditions.
|
||||
// 1) The mouse is visible and no conditional hide has been specified.
|
||||
// (perform normal region checking with possible hide)
|
||||
// 2) The mouse is hidden and no conditional hide as been specified.
|
||||
// (record region and do nothing)
|
||||
// 3) The mouse is visible and a conditional region has been specified
|
||||
// (expand region and perform check with possible hide).
|
||||
// 4) The mouse is already hidden by a previous conditional.
|
||||
// (expand region and do nothing)
|
||||
//
|
||||
// First: Set or expand the region according to the specified parameters
|
||||
if (!MCCount) {
|
||||
MouseCXLeft = x1;
|
||||
MouseCYUpper = y1;
|
||||
MouseCXRight = x2;
|
||||
MouseCYLower = y2;
|
||||
} else {
|
||||
MouseCXLeft = MIN(x1, MouseCXLeft);
|
||||
MouseCYUpper = MIN(y1, MouseCYUpper);
|
||||
MouseCXRight = MAX(x2, MouseCXRight);
|
||||
MouseCYLower = MAX(y2, MouseCYLower);
|
||||
}
|
||||
//
|
||||
// If the mouse isn't already hidden, then check its location against
|
||||
// the hiding region and hide if necessary.
|
||||
//
|
||||
if (!(MCFlags & CONDHIDDEN)) {
|
||||
GetCursorPos(&pt);
|
||||
if (MouseBuffX >= MouseCXLeft && MouseBuffX <= MouseCXRight && MouseBuffY >= MouseCYUpper && MouseBuffY <= MouseCYLower) {
|
||||
Low_Hide_Mouse();
|
||||
MCFlags |= CONDHIDDEN;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Record the fact that a conditional hide was called and then exit
|
||||
//
|
||||
//
|
||||
MCFlags |= CONDHIDE;
|
||||
MCCount++;
|
||||
MouseUpdate--;
|
||||
|
||||
}
|
||||
void WWMouseClass::Conditional_Show_Mouse(void)
|
||||
{
|
||||
MouseUpdate++;
|
||||
|
||||
//
|
||||
// if there are any nested hides then dec the count
|
||||
//
|
||||
if (MCCount) {
|
||||
MCCount--;
|
||||
//
|
||||
// If the mouse is now not hidden and it had actually been
|
||||
// hidden before then display it.
|
||||
//
|
||||
if (!MCCount) {
|
||||
if (MCFlags & CONDHIDDEN) {
|
||||
Show_Mouse();
|
||||
}
|
||||
MCFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MouseUpdate--;
|
||||
}
|
||||
|
||||
|
||||
void WWMouseClass::Draw_Mouse(GraphicViewPortClass *scr)
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
if (State != 0) return;
|
||||
MouseUpdate++;
|
||||
//
|
||||
// Get the position that the mouse is currently located at
|
||||
//
|
||||
GetCursorPos(&pt);
|
||||
if (MCFlags & CONDHIDE && pt.x >= MouseCXLeft && pt.x <= MouseCXRight && pt.y >= MouseCYUpper && pt.y <= MouseCYLower) {
|
||||
Hide_Mouse();
|
||||
MCFlags |= CONDHIDDEN;
|
||||
} else {
|
||||
//
|
||||
// If the mouse is already visible then just ignore the problem.
|
||||
//
|
||||
EraseFlags = TRUE;
|
||||
|
||||
//
|
||||
// Try to lock the screen - dont do video stuff if we cant.
|
||||
//
|
||||
if (scr->Lock()){
|
||||
//
|
||||
// Save off the area behind the mouse into two different buffers, one
|
||||
// which will be used to restore the mouse and the other which will
|
||||
// be used to restore the hidden surface when we get a chance.
|
||||
//
|
||||
Mouse_Shadow_Buffer(this, scr, EraseBuffer, pt.x, pt.y, MouseXHot, MouseYHot, 1);
|
||||
memcpy(MouseBuffer, EraseBuffer, MaxWidth * MaxHeight);
|
||||
//
|
||||
// Draw the mouse in its new location
|
||||
//
|
||||
::Draw_Mouse(this, scr, pt.x, pt.y);
|
||||
//
|
||||
// Save off the positions that we saved the buffer from
|
||||
//
|
||||
EraseBuffX = pt.x;
|
||||
MouseBuffX = pt.x;
|
||||
EraseBuffY = pt.y;
|
||||
MouseBuffY = pt.y;
|
||||
EraseBuffHotX = MouseXHot;
|
||||
EraseBuffHotY = MouseYHot;
|
||||
//
|
||||
// Unlock the screen and lets get moving.
|
||||
//
|
||||
scr->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
MouseUpdate--;
|
||||
}
|
||||
|
||||
void WWMouseClass::Erase_Mouse(GraphicViewPortClass *scr, int forced)
|
||||
{
|
||||
//
|
||||
// If we are forcing the redraw of a mouse we already managed to
|
||||
// restore then just get outta here.
|
||||
//
|
||||
if (forced && EraseBuffX == -1 && EraseBuffY == -1) return;
|
||||
|
||||
MouseUpdate++;
|
||||
|
||||
//
|
||||
// If this is not a forced call, only update the mouse is we can legally
|
||||
// lock the buffer.
|
||||
//
|
||||
if (!forced) {
|
||||
#if(0)
|
||||
if (scr->Lock()) {
|
||||
//
|
||||
// If the surface has not already been restore then restore it and erase the
|
||||
// restoration coordinates so we don't accidentally do it twice.
|
||||
//
|
||||
if (EraseBuffX != -1 || EraseBuffY != -1) {
|
||||
Mouse_Shadow_Buffer(this, scr, EraseBuffer, EraseBuffX, EraseBuffY, 0);
|
||||
EraseBuffX = -1;
|
||||
EraseBuffY = -1;
|
||||
}
|
||||
//
|
||||
// We are done writing to the buffer so unlock it.
|
||||
//
|
||||
scr->Unlock();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
//
|
||||
// If the surface has not already been restore then restore it and erase the
|
||||
// restoration coordinates so we don't accidentally do it twice.
|
||||
//
|
||||
if (EraseBuffX != -1 || EraseBuffY != -1) {
|
||||
if (scr->Lock()){
|
||||
Mouse_Shadow_Buffer(this, scr, EraseBuffer, EraseBuffX, EraseBuffY, EraseBuffHotX, EraseBuffHotY, 0);
|
||||
scr->Unlock();
|
||||
}
|
||||
EraseBuffX = -1;
|
||||
EraseBuffY = -1;
|
||||
}
|
||||
}
|
||||
MouseUpdate--;
|
||||
EraseFlags = FALSE;
|
||||
}
|
||||
|
||||
int WWMouseClass::Get_Mouse_State(void)
|
||||
{
|
||||
return(State);
|
||||
}
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: int - returns the mouses current x position in pixels *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
int WWMouseClass::Get_Mouse_X(void)
|
||||
{
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
return(pt.x);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Get_Mouse_Y -- returns the mouses current y position in pixels *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: int - returns the mouses current y position in pixels *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
int WWMouseClass::Get_Mouse_Y(void)
|
||||
{
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
return(pt.y);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* WWKeyboardClass::Get_Mouse_XY -- Returns the mouses x,y position via reference vars *
|
||||
* *
|
||||
* INPUT: int &x - variable to return the mouses x position in pixels *
|
||||
* int &y - variable to return the mouses y position in pixels *
|
||||
* *
|
||||
* OUTPUT: none - output is via reference variables *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/17/1995 PWG : Created. *
|
||||
*=============================================================================================*/
|
||||
void WWMouseClass::Get_Mouse_XY(int &x, int &y)
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
GetCursorPos(&pt);
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
|
||||
#pragma off(unreferenced)
|
||||
|
||||
void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 )
|
||||
{
|
||||
static BOOL in_mouse_callback = false;
|
||||
|
||||
if (_Mouse && !in_mouse_callback) {
|
||||
in_mouse_callback = TRUE;
|
||||
_Mouse->Process_Mouse();
|
||||
in_mouse_callback = FALSE;
|
||||
}
|
||||
}
|
||||
#pragma on(unreferenced)
|
||||
|
||||
void Hide_Mouse(void)
|
||||
{
|
||||
if (!_Mouse) return;
|
||||
_Mouse->Hide_Mouse();
|
||||
}
|
||||
|
||||
void Show_Mouse(void)
|
||||
{
|
||||
if (!_Mouse) return;
|
||||
_Mouse->Show_Mouse();
|
||||
}
|
||||
|
||||
void Conditional_Hide_Mouse(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
if (!_Mouse) return;
|
||||
_Mouse->Conditional_Hide_Mouse(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void Conditional_Show_Mouse(void)
|
||||
{
|
||||
if (!_Mouse) return;
|
||||
_Mouse->Conditional_Show_Mouse();
|
||||
}
|
||||
|
||||
int Get_Mouse_State(void)
|
||||
{
|
||||
if (!_Mouse) return(0);
|
||||
return(_Mouse->Get_Mouse_State());
|
||||
}
|
||||
|
||||
void *Set_Mouse_Cursor(int hotx, int hoty, void *cursor)
|
||||
{
|
||||
if (!_Mouse) return(0);
|
||||
return(_Mouse->Set_Cursor(hotx,hoty,cursor));
|
||||
}
|
||||
|
||||
int Get_Mouse_X(void)
|
||||
{
|
||||
if (!_Mouse) return(0);
|
||||
return(_Mouse->Get_Mouse_X());
|
||||
}
|
||||
|
||||
int Get_Mouse_Y(void)
|
||||
{
|
||||
if (!_Mouse) return(0);
|
||||
return(_Mouse->Get_Mouse_Y());
|
||||
}
|
||||
128
WIN32LIB/SRCDEBUG/NEWDEL.CPP
Normal file
128
WIN32LIB/SRCDEBUG/NEWDEL.CPP
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Memory system. *
|
||||
* *
|
||||
* File Name : NEWDEL.CPP *
|
||||
* *
|
||||
* Programmer : Scott K. Bowen *
|
||||
* *
|
||||
* Start Date : June 21, 1994 *
|
||||
* *
|
||||
* Last Update : October 20, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* operator NEW -- Overides the global new function. *
|
||||
* operator delete -- Overides the global delete function. *
|
||||
* operator NEW[] -- Overides the array version of new. *
|
||||
* operator delete[] -- Overides the array version of delete[] *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "wwmem.h"
|
||||
|
||||
|
||||
/*=========================================================================*/
|
||||
/* The following PRIVATE functions are in this file: */
|
||||
/*=========================================================================*/
|
||||
|
||||
/*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* OPERATOR NEW -- Overides the global new function. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void * operator new(size_t size)
|
||||
{
|
||||
return (Alloc((unsigned long) size, MEM_NEW));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* OPERATOR NEW[] -- Overides the array version of new. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void * operator new[](size_t size)
|
||||
{
|
||||
return (Alloc((unsigned long) size, MEM_NEW));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* OPERATOR DELETE -- Overides the global delete function. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/21/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void operator delete(void *ptr)
|
||||
{
|
||||
Free(ptr);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* OPERATOR DELETE[] -- Overides the array version of delete[] *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/20/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void operator delete[](void *ptr)
|
||||
{
|
||||
Free(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
755
WIN32LIB/SRCDEBUG/OLSOSDEC.ASM
Normal file
755
WIN32LIB/SRCDEBUG/OLSOSDEC.ASM
Normal file
@@ -0,0 +1,755 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* Copyright (c) 1994, HMI, INC. All Rights Reserved
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* FILE
|
||||
;* soscodec.asm
|
||||
;*
|
||||
;* DESCRIPTION
|
||||
;* HMI SOS ADPCM compression/decompression.
|
||||
;*
|
||||
;* PROGRAMMER
|
||||
;* Nick Skrepetos
|
||||
;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom)
|
||||
;* Bill Petro (Added stereo support)
|
||||
;* DATE
|
||||
;* Febuary 15, 1995
|
||||
;*
|
||||
;*---------------------------------------------------------------------------
|
||||
;*
|
||||
;* PUBLIC
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ??
|
||||
|
||||
|
||||
DPMI_INTR equ 31h
|
||||
IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI.
|
||||
IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI.
|
||||
|
||||
STRUC sCompInfo
|
||||
lpSource DD ? ;Compressed data pointer
|
||||
lpDest DD ? ;Uncompressed data pointer
|
||||
dwCompSize DD ? ;Compressed size
|
||||
dwUnCompSize DD ? ;Uncompressed size
|
||||
|
||||
dwSampleIndex DD ? ;Index into sample
|
||||
dwPredicted DD ? ;Next predicted value
|
||||
dwDifference DD ? ;Difference from last sample
|
||||
wCodeBuf DW ? ;Holds 2 nibbles for decompression
|
||||
wCode DW ? ;Current 4 bit code
|
||||
wStep DW ? ;Step value in table
|
||||
wIndex DW ? ;Index into step table
|
||||
|
||||
dwSampleIndex2 DD ? ;Index into sample
|
||||
dwPredicted2 DD ? ;Next predicted value
|
||||
dwDifference2 DD ? ;Difference from last sample
|
||||
wCodeBuf2 DW ? ;Holds 2 nibbles for decompression
|
||||
wCode2 DW ? ;Current 4 bit code
|
||||
wStep2 DW ? ;Step value in table
|
||||
wIndex2 DW ? ;Index into step table
|
||||
|
||||
wBitSize DW ? ;Bit size for decompression
|
||||
wChannels DW ? ;number of channels
|
||||
ENDS sCompInfo
|
||||
|
||||
DATASEG
|
||||
|
||||
|
||||
InitFlags DD 0 ; Flags to indicate what has been initialized.
|
||||
|
||||
|
||||
LABEL LockedDataStart BYTE
|
||||
|
||||
;* Index table for stepping into step table
|
||||
|
||||
wCODECIndexTab DW -1,-1,-1,-1,2,4,6,8
|
||||
DW -1,-1,-1,-1,2,4,6,8
|
||||
|
||||
|
||||
;Lookup table of replacement values
|
||||
;The actual sound value is replaced with an index to lookup in this table
|
||||
;The index only takes up a nibble(4bits) and represents an int(16bits)
|
||||
;Essentially:
|
||||
;Get a value
|
||||
;compare it with the value before it
|
||||
;find closest value in table and store the index into the table
|
||||
;if i'm going down then negitize it
|
||||
;go to next byte.
|
||||
|
||||
;Theory for stereo:
|
||||
;1)handle stereo and mono in two seperate loops. cleaner...
|
||||
;start at byte 0 and skip every other byte(or word) both write and read
|
||||
;when we get done
|
||||
; set start byte to 1 and do it again
|
||||
|
||||
|
||||
|
||||
|
||||
;This table essentialy round off to closes values in 3 distinct bands
|
||||
; precalculated and optimized(i guess) for human hearing.
|
||||
|
||||
wCODECStepTab DW 7, 8, 9, 10, 11, 12, 13,14
|
||||
DW 16, 17, 19, 21, 23, 25, 28, 31
|
||||
DW 34, 37, 41, 45, 50, 55, 60, 66
|
||||
DW 73, 80, 88, 97, 107, 118, 130, 143
|
||||
DW 157, 173, 190, 209, 230, 253, 279, 307
|
||||
DW 337, 371, 408, 449, 494, 544, 598, 658
|
||||
DW 724, 796, 876, 963, 1060, 1166, 1282, 1411
|
||||
DW 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024
|
||||
DW 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484
|
||||
DW 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899
|
||||
DW 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794
|
||||
DW 32767
|
||||
|
||||
;dwCODECByteIndex DD 0 ; this is when to stop compressing
|
||||
;dwCODECTempStep DD 0 ; tempory storage for step value
|
||||
;wCODECMask DW 0 ; Current mask
|
||||
|
||||
LABEL LockedDataEnd BYTE
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
LABEL LockedCodeStart BYTE
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* sosCODECInitStream - Initialize compression stream.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* sosCODECInitStream(CompInfo)
|
||||
;*
|
||||
;* void sosCODECInitStream(_SOS_COMPRESS_INFO *);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;* Initialize compression stream for compression and decompression.
|
||||
;*
|
||||
;* INPUTS
|
||||
;* CompInfo - Compression information structure.
|
||||
;*
|
||||
;* RESULT
|
||||
;* NONE
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
GLOBAL C sosCODECInitStream:NEAR
|
||||
PROC sosCODECInitStream C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
|
||||
mov eax,[sSOSInfo]
|
||||
mov [(sCompInfo eax).wIndex],0 ; starting index 0
|
||||
mov [(sCompInfo eax).wStep],7 ; start with a step of 7
|
||||
mov [(sCompInfo eax).dwPredicted],0 ; no predicted value
|
||||
mov [(sCompInfo eax).dwSampleIndex],0 ;start at head of index
|
||||
mov [(sCompInfo eax).wIndex2],0 ; starting index 0
|
||||
mov [(sCompInfo eax).wStep2],7 ; start with a step of 7
|
||||
mov [(sCompInfo eax).dwPredicted2],0 ; no predicted value
|
||||
mov [(sCompInfo eax).dwSampleIndex2],0 ;start at head of index
|
||||
ret
|
||||
|
||||
ENDP sosCODECInitStream
|
||||
|
||||
|
||||
|
||||
;****************************************************************************
|
||||
;*
|
||||
;* NAME
|
||||
;* sosCODECDecompressData - Decompress audio data.
|
||||
;*
|
||||
;* SYNOPSIS
|
||||
;* Size = sosCODECDecompressData(CompInfo, NumBytes)
|
||||
;*
|
||||
;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long);
|
||||
;*
|
||||
;* FUNCTION
|
||||
;* Decompress data from a 4:1 ADPCM compressed stream. The number of
|
||||
;* bytes decompressed is returned.
|
||||
;*
|
||||
;* INPUTS
|
||||
;* CompInfo - Compress information structure.
|
||||
;* NumBytes - Number of bytes to compress.
|
||||
;*
|
||||
;* RESULT
|
||||
;* Size - Size of decompressed data.
|
||||
;*
|
||||
;****************************************************************************
|
||||
|
||||
GLOBAL C General_sosCODECDecompressData:NEAR
|
||||
PROC General_sosCODECDecompressData C NEAR
|
||||
|
||||
ARG sSOSInfo:NEAR PTR
|
||||
ARG wBytes:DWORD
|
||||
|
||||
local dwCODECBytesProcessed:dword ;bytes to decompress
|
||||
local dwCODECByteIndex:dword ;this is when to stop compressing
|
||||
; these need to be local if the function is to be reenterant
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
;*---------------------------------------------------------------------------
|
||||
;* Initialize
|
||||
;*---------------------------------------------------------------------------
|
||||
|
||||
mov ebx,[sSOSInfo]
|
||||
mov eax,[wBytes]
|
||||
mov [dwCODECBytesProcessed],eax
|
||||
mov [(sCompInfo ebx).dwSampleIndex],0 ;start at head of index
|
||||
mov [(sCompInfo ebx).dwSampleIndex2],0 ;start at head of index
|
||||
|
||||
;Check for 16 bit decompression
|
||||
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??skipByteDivide
|
||||
|
||||
shr eax,1 ;Divide size by two
|
||||
|
||||
??skipByteDivide:
|
||||
mov [dwCODECByteIndex],eax
|
||||
mov esi,[(sCompInfo ebx).lpSource]
|
||||
mov edi,[(sCompInfo ebx).lpDest]
|
||||
cmp [(sCompInfo ebx).wChannels],2 ;stereo check
|
||||
je ??mainloopl ;do left side first
|
||||
|
||||
; Determine if sample index is even or odd. This will determine
|
||||
; if we need to get a new token or not.
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
;Main Mono Loop
|
||||
;---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
??mainloop:
|
||||
test [(sCompInfo ebx).dwSampleIndex],1 ;odd ??
|
||||
je short ??fetchToken ; if so get new token
|
||||
xor eax,eax ;else shift int codebuf
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf] ;ored with Code
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
jmp short ??calcDifference
|
||||
|
||||
??fetchToken:
|
||||
xor eax,eax ;get a new token
|
||||
mov al,[esi] ;put in codebuf
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
inc esi
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax ;and then code
|
||||
|
||||
??calcDifference:
|
||||
mov [(sCompInfo ebx).dwDifference],0 ;reset diff
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep] ;cx is step value
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4
|
||||
add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
|
||||
|
||||
??no4:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no2:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no1:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8
|
||||
neg [(sCompInfo ebx).dwDifference] ;Negate diff
|
||||
|
||||
??no8:
|
||||
; add difference to predicted value.
|
||||
|
||||
mov eax,[(sCompInfo ebx).dwPredicted]
|
||||
add eax,[(sCompInfo ebx).dwDifference]
|
||||
|
||||
; make sure there is no under or overflow.
|
||||
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflow
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflow:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflow
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflow:
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bit
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,2
|
||||
jmp short ??adjustIndex
|
||||
|
||||
??output8Bit:
|
||||
; output 8 bit sample
|
||||
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
inc edi
|
||||
|
||||
??adjustIndex:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex],ax ;check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex],8000h
|
||||
jb short ??checkOverflow
|
||||
mov [(sCompInfo ebx).wIndex],0 ;reset index to zero
|
||||
jmp short ??adjustStep
|
||||
|
||||
??checkOverflow:
|
||||
cmp [(sCompInfo ebx).wIndex],88 ;check if wIndex > 88
|
||||
jbe short ??adjustStep
|
||||
mov [(sCompInfo ebx).wIndex],88 ;reset index to 88
|
||||
|
||||
??adjustStep:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex],1
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
dec [dwCODECByteIndex]
|
||||
jne ??mainloop
|
||||
jmp ??exitout
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Left Channel Start
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
|
||||
??mainloopl:
|
||||
test [(sCompInfo ebx).dwSampleIndex],1
|
||||
je short ??fetchTokenl
|
||||
|
||||
xor eax,eax
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf]
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
jmp short ??calcDifferencel
|
||||
|
||||
??fetchTokenl:
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
mov [(sCompInfo ebx).wCodeBuf],ax
|
||||
add esi,2 ;2 for stereo
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode],ax
|
||||
|
||||
??calcDifferencel:
|
||||
; reset difference
|
||||
|
||||
mov [(sCompInfo ebx).dwDifference],0
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep]
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4l
|
||||
add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
|
||||
|
||||
??no4l:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2l
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no2l:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1l
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
|
||||
??no1l:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8l
|
||||
neg [(sCompInfo ebx).dwDifference] ;Negate diff
|
||||
|
||||
??no8l:
|
||||
; add difference to predicted value.
|
||||
|
||||
mov eax,[(sCompInfo ebx).dwPredicted]
|
||||
add eax,[(sCompInfo ebx).dwDifference]
|
||||
|
||||
; make sure there is no under or overflow.
|
||||
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflowl
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflowl:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflowl
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflowl:
|
||||
mov [(sCompInfo ebx).dwPredicted],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bitl
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,4 ;4 for stereo
|
||||
jmp short ??adjustIndexl
|
||||
|
||||
??output8Bitl:
|
||||
; output 8 bit sample
|
||||
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
add edi,2 ;2 for stereo
|
||||
|
||||
??adjustIndexl:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex],ax
|
||||
; check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex],8000h
|
||||
jb short ??checkOverflowl
|
||||
mov [(sCompInfo ebx).wIndex],0
|
||||
jmp short ??adjustStepl ;reset index to zero
|
||||
|
||||
|
||||
??checkOverflowl:
|
||||
|
||||
cmp [(sCompInfo ebx).wIndex],88 ; check if wIndex > 88
|
||||
jbe short ??adjustStepl
|
||||
mov [(sCompInfo ebx).wIndex],88 ; reset index to 88
|
||||
|
||||
??adjustStepl:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex],1
|
||||
mov [(sCompInfo ebx).wStep],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
sub [dwCODECByteIndex],2
|
||||
jne ??mainloopl
|
||||
;----------------------------------------------------------------------------
|
||||
; Right Side Setup
|
||||
;----------------------------------------------------------------------------
|
||||
mov eax,[wBytes]
|
||||
mov [dwCODECBytesProcessed],eax
|
||||
mov esi,[(sCompInfo ebx).lpSource]
|
||||
mov edi,[(sCompInfo ebx).lpDest]
|
||||
inc esi ; skip left channel
|
||||
inc edi ; skip left channel
|
||||
cmp [(sCompInfo ebx).wBitSize],16 ;16 bit ??
|
||||
je short ??doByteDivide
|
||||
mov [dwCODECByteIndex],eax
|
||||
jmp short ??mainloopr
|
||||
|
||||
??doByteDivide:
|
||||
shr eax,1 ;Divide size by two
|
||||
inc edi ; 16 bit so skip 1 more
|
||||
mov [dwCODECByteIndex],eax
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
;Right Channel Start
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
|
||||
??mainloopr:
|
||||
test [(sCompInfo ebx).dwSampleIndex2],1
|
||||
je short ??fetchTokenr
|
||||
xor eax,eax
|
||||
mov ax,[(sCompInfo ebx).wCodeBuf2]
|
||||
shr eax,4
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode2],ax
|
||||
jmp short ??calcDifferencer
|
||||
|
||||
??fetchTokenr:
|
||||
xor eax,eax
|
||||
mov al,[esi]
|
||||
mov [(sCompInfo ebx).wCodeBuf2],ax
|
||||
add esi,2 ;2 for stereo
|
||||
and eax,000Fh
|
||||
mov [(sCompInfo ebx).wCode2],ax
|
||||
|
||||
??calcDifferencer:
|
||||
; reset difference
|
||||
|
||||
mov [(sCompInfo ebx).dwDifference2],0
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wStep2]
|
||||
test eax,4 ;Check for wCode & 4
|
||||
je short ??no4r
|
||||
add [(sCompInfo ebx).dwDifference2],ecx ;Add wStep
|
||||
|
||||
??no4r:
|
||||
test eax,2 ;Check for wCode & 2
|
||||
je short ??no2r
|
||||
mov edx,ecx ;Add wStep >> 1
|
||||
shr edx,1
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
|
||||
??no2r:
|
||||
test eax,1 ;Check for wCode & 1
|
||||
je short ??no1r
|
||||
mov edx,ecx ;Add wStep >> 2
|
||||
shr edx,2
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
|
||||
??no1r:
|
||||
mov edx,ecx ;Add in wStep >> 3
|
||||
shr edx,3
|
||||
add [(sCompInfo ebx).dwDifference2],edx
|
||||
test eax,8 ;Check for wCode & 8
|
||||
je short ??no8r
|
||||
neg [(sCompInfo ebx).dwDifference2] ;Negate diff
|
||||
|
||||
??no8r:
|
||||
; add difference to predicted value.
|
||||
mov eax,[(sCompInfo ebx).dwPredicted2]
|
||||
add eax,[(sCompInfo ebx).dwDifference2]
|
||||
cmp eax,7FFFh
|
||||
jl short ??noOverflowr
|
||||
mov eax,7FFFh
|
||||
|
||||
??noOverflowr:
|
||||
cmp eax,0FFFF8000h
|
||||
jg short ??noUnderflowr
|
||||
mov eax,0FFFF8000h
|
||||
|
||||
??noUnderflowr:
|
||||
mov [(sCompInfo ebx).dwPredicted2],eax
|
||||
cmp [(sCompInfo ebx).wBitSize],16
|
||||
jne short ??output8Bitr
|
||||
mov [edi],ax ;Output 16bit sample
|
||||
add edi,4 ;4 for stereo ***
|
||||
jmp short ??adjustIndexr
|
||||
|
||||
??output8Bitr:
|
||||
; output 8 bit sample
|
||||
xor ah,80h
|
||||
mov [edi],ah
|
||||
add edi,2 ;2 for stereo
|
||||
|
||||
??adjustIndexr:
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wCode2]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECIndexTab + ecx]
|
||||
add [(sCompInfo ebx).wIndex2],ax
|
||||
; check if wIndex < 0
|
||||
cmp [(sCompInfo ebx).wIndex2],8000h
|
||||
jb short ??checkOverflowr
|
||||
; reset index to zero
|
||||
mov [(sCompInfo ebx).wIndex2],0
|
||||
jmp short ??adjustStepr
|
||||
|
||||
??checkOverflowr:
|
||||
; check if wIndex > 88
|
||||
cmp [(sCompInfo ebx).wIndex2],88
|
||||
jbe short ??adjustStepr
|
||||
mov [(sCompInfo ebx).wIndex2],88 ; reset index to 88
|
||||
|
||||
??adjustStepr:
|
||||
; fetch wIndex so we can fetch new step value
|
||||
|
||||
xor ecx,ecx
|
||||
mov cx,[(sCompInfo ebx).wIndex2]
|
||||
xor eax,eax
|
||||
shl ecx,1
|
||||
mov ax,[wCODECStepTab + ecx]
|
||||
|
||||
; advance index and store step value
|
||||
|
||||
add [(sCompInfo ebx).dwSampleIndex2],1
|
||||
mov [(sCompInfo ebx).wStep2],ax
|
||||
|
||||
; decrement bytes processed and loop back.
|
||||
|
||||
sub [dwCODECByteIndex],2
|
||||
jne ??mainloopr
|
||||
|
||||
|
||||
??exitout:
|
||||
; don't think we need this but just in case i'll leave it here!!
|
||||
|
||||
; mov [(sCompInfo ebx).lpSource],esi
|
||||
; mov [(sCompInfo ebx).lpDest],edi
|
||||
; set up return value for number of bytes processed.
|
||||
mov eax,[dwCODECBytesProcessed]
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
ENDP General_sosCODECDecompressData
|
||||
|
||||
LABEL LockedCodeEnd BYTE
|
||||
|
||||
;***************************************************************************
|
||||
;* sosCODEC_LOCK -- locks the JLB audio decompression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is lock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL sosCODEC_Lock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL C sosCODEC_Lock:NEAR
|
||||
PROC sosCODEC_Lock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
;
|
||||
; Lock the code that is used by the sos decompression method.
|
||||
;
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
or [InitFlags], IF_LOCKED_PM_CODE
|
||||
|
||||
;
|
||||
; Lock the data used by the sos decompression method.
|
||||
;
|
||||
mov eax,0600h ; function number.
|
||||
mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedDataEnd ; edi will have size of region in bytes.
|
||||
shld ebx,ecx,16
|
||||
sub edi, ecx
|
||||
shld esi,edi,16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
|
||||
or [InitFlags], IF_LOCKED_PM_DATA
|
||||
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
ENDP sosCODEC_Lock
|
||||
|
||||
;***************************************************************************
|
||||
;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
|
||||
;* *
|
||||
;* PROTO: BOOL sosCODEC_Unlock(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 06/26/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
GLOBAL C sosCODEC_Unlock:NEAR
|
||||
PROC sosCODEC_Unlock C NEAR USES ebx ecx edx esi edi
|
||||
|
||||
test [InitFlags],IF_LOCKED_PM_CODE
|
||||
jz ??code_not_locked
|
||||
|
||||
mov eax , 0601h
|
||||
mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error
|
||||
|
||||
??code_not_locked:
|
||||
test [InitFlags],IF_LOCKED_PM_DATA
|
||||
jz ??data_not_locked
|
||||
|
||||
mov ax,0601h ; set es to descriptor of data.
|
||||
mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
|
||||
mov edi,OFFSET LockedDataEnd ; edx will have size of region in bytes.
|
||||
sub edi,ecx ; - figure size.
|
||||
shld ebx , ecx , 16
|
||||
shld esi , edi , 16
|
||||
int DPMI_INTR ; do call.
|
||||
jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
|
||||
|
||||
??data_not_locked:
|
||||
mov [InitFlags],0
|
||||
mov eax,1
|
||||
jmp ??exit
|
||||
??error:
|
||||
xor eax,eax
|
||||
??exit:
|
||||
ret
|
||||
ENDP sosCODEC_Unlock
|
||||
|
||||
|
||||
END
|
||||
150
WIN32LIB/SRCDEBUG/OPSYS.ASM
Normal file
150
WIN32LIB/SRCDEBUG/OPSYS.ASM
Normal file
@@ -0,0 +1,150 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/system/rcs/opsys.asm 1.1 1994/04/18 09:14:12 jeff_wilson Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Operating System Flags *
|
||||
;* *
|
||||
;* File Name : OPSYS.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott Bowen *
|
||||
;* *
|
||||
;* Start Date : January 26, 1993 *
|
||||
;* *
|
||||
;* Last Update : January 26, 1993 [SB] *
|
||||
;* *
|
||||
;* Updated to 32bit protected mode JAW *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Operating_System -- Determines what the operating system is. *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
GLOBAL C Operating_System :NEAR
|
||||
GLOBAL C OperatingSystem :WORD
|
||||
|
||||
DOS equ 1
|
||||
WIN31STD equ 2
|
||||
WIN31ENH equ 3
|
||||
WIN30ENH equ 4
|
||||
WIN30STD equ 5
|
||||
WIN30REAL equ 6
|
||||
|
||||
DATASEG
|
||||
|
||||
OperatingSystem dw 0
|
||||
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* Operating_System -- Determines what the operating system is. *
|
||||
;* *
|
||||
;* INPUT: NONE. *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 01/26/1993 SB : Created. *
|
||||
;*=========================================================================*
|
||||
PROC Operating_System C near
|
||||
USES ebx,ecx,edx,es,edi
|
||||
|
||||
|
||||
; Check for Windows 3.1
|
||||
mov eax,160Ah ; WIN31CHECK
|
||||
int 2fh
|
||||
or ax,ax
|
||||
jz short RunningUnderWin31
|
||||
|
||||
;check for Windows 3.0 enhanced mode
|
||||
mov eax,1600h ; WIN386CHECK
|
||||
int 2fh
|
||||
mov bl,al
|
||||
mov eax,WIN30ENH
|
||||
test bl,7fh
|
||||
jnz short Exit
|
||||
|
||||
;check for 3.0 WINOLDAP
|
||||
mov eax,4680h ; IS_WINOLDAP_ACTIVE
|
||||
int 2fh
|
||||
or eax,eax
|
||||
jnz short NotRunningUnderWin
|
||||
|
||||
; rule out MS-DOS 5.0 task switcher
|
||||
mov eax,4b02h ; detect switcher
|
||||
push ebx
|
||||
push es
|
||||
push edi
|
||||
xor ebx,ebx
|
||||
mov edi,ebx
|
||||
mov es,bx
|
||||
int 2fh
|
||||
pop edi
|
||||
pop es
|
||||
pop ebx
|
||||
or eax,eax
|
||||
jz short NotRunningUnderWin ; MS-DOS 5.0 task switcher found.
|
||||
|
||||
; check for standrd mode Windows 3.0
|
||||
mov eax,1605h ;PMODE_START
|
||||
int 2fh
|
||||
mov eax,WIN30STD
|
||||
cmp ecx,-1
|
||||
jz short Exit
|
||||
|
||||
;check for real mode Windows 3.0
|
||||
mov eax,1606h ; PMODE_STOP
|
||||
int 2fh
|
||||
mov eax,WIN30REAL
|
||||
jmp SHORT Exit
|
||||
|
||||
RunningUnderWin31:
|
||||
; At this point: CX == 3 means Windows 3.1 enhanced mode.
|
||||
; CX == 2 means Windows 3.1 standard mode.
|
||||
mov eax,WIN31STD
|
||||
cmp ecx,2
|
||||
je short Exit
|
||||
|
||||
mov eax,WIN31ENH
|
||||
jmp SHORT Exit
|
||||
|
||||
NotRunningUnderWin:
|
||||
mov eax,DOS
|
||||
|
||||
Exit:
|
||||
mov [WORD PTR OperatingSystem], ax
|
||||
ret
|
||||
|
||||
ENDP Operating_System
|
||||
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
END
|
||||
132
WIN32LIB/SRCDEBUG/PACK2PLN.ASM
Normal file
132
WIN32LIB/SRCDEBUG/PACK2PLN.ASM
Normal file
@@ -0,0 +1,132 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; $Header: g:/library/wwlib32/file/rcs/pack2pln.asm 1.1 1994/04/22 18:07:46 scott_bowen Exp $
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Library *
|
||||
;* *
|
||||
;* File Name : PACK2PLN.ASM *
|
||||
;* *
|
||||
;* Programmer : Scott K. Bowen *
|
||||
;* *
|
||||
;* Start Date : November 20, 1991 *
|
||||
;* *
|
||||
;* Last Update : April 22, 1994 [SKB] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
LOCALS ??
|
||||
|
||||
|
||||
;******************************************************************************
|
||||
; External declares so these functions can be called
|
||||
;
|
||||
GLOBAL Pack_2_Plane:NEAR
|
||||
|
||||
CODESEG
|
||||
|
||||
;***************************************************************************
|
||||
;* PACK_2_PLANE -- packed to planar scanline conversion *
|
||||
;* *
|
||||
;* INPUT: BYTE *buffer (far) -- pointer to planar output buffer *
|
||||
;* BYTE *pageptr (far) -- pointer to current row in packed page *
|
||||
;* WORD planebit -- current bit used in plane -- use only low byte *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* Return result in buffer. *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 11/20/1991 SB : Created. *
|
||||
;* 04/22/1994 SKB : Converted to 32 bit library. *
|
||||
;*=========================================================================*
|
||||
; *
|
||||
; This is the original function that is converted to asm
|
||||
;
|
||||
;PRIVATE VOID Pack_2_Plane(UBYTE * buffer, BYTE * pageptr, BYTE planebit)
|
||||
;{
|
||||
; WORD currbit=0x80; // current bit to be written to
|
||||
; WORD pixel; // current pixel in row used as a counter;
|
||||
;
|
||||
; buffer--; // will be incremented at the start
|
||||
; for (currbit = 0, pixel = 0; pixel < 320; pixel++) {
|
||||
; if (!currbit) {
|
||||
; currbit = 0x80; // reset bit 7
|
||||
; buffer++; // go to next byte in buffer
|
||||
; *buffer = 0; // clear byte so we only need to set bits needed
|
||||
; }
|
||||
; if (planebit & *pageptr++)
|
||||
; *buffer |= currbit; // set bit in destination if plane was set is source
|
||||
;
|
||||
; currbit >>= 1; // shift destination bit one right
|
||||
; }
|
||||
;}
|
||||
|
||||
PROC Pack_2_Plane C NEAR
|
||||
USES ebx,ecx,esi,edi
|
||||
ARG buffer:DWORD
|
||||
ARG page:DWORD
|
||||
ARG planebit:WORD
|
||||
|
||||
|
||||
mov edi,[buffer]
|
||||
mov esi,[page]
|
||||
|
||||
mov ax,[planebit] ; move bit set for current plane (planebit) to ax
|
||||
; the low byte will only be used
|
||||
|
||||
mov ecx,320d ; set counter to 320 columns (320x200 picture)
|
||||
mov ah,80h ; set bit 7 of current_bit
|
||||
dec edi ; this will get incremented at the start
|
||||
|
||||
??top_loop: ; while (columns left)
|
||||
cmp ah,80h ; if current_bit is bit 7
|
||||
jnz short ??same_dest
|
||||
; Then
|
||||
inc edi ; buffer++ increment pointer
|
||||
mov [BYTE PTR edi],0 ; *buffer = 0
|
||||
|
||||
??same_dest: ; EndIf
|
||||
mov bl,al
|
||||
and bl,[esi] ; if (planebit & *pageptr)
|
||||
jz short ??no_set_bit
|
||||
|
||||
or [BYTE PTR edi],ah ; Then *buffer |= current_bit
|
||||
|
||||
??no_set_bit:
|
||||
inc esi ; pageptr++ goto next in source byte
|
||||
ror ah,1 ; rotate current_bit right one
|
||||
dec ecx ;
|
||||
jnz ??top_loop
|
||||
|
||||
ret
|
||||
|
||||
ENDP Pack_2_Plane
|
||||
|
||||
END
|
||||
|
||||
152
WIN32LIB/SRCDEBUG/PAGFAULT.ASM
Normal file
152
WIN32LIB/SRCDEBUG/PAGFAULT.ASM
Normal file
@@ -0,0 +1,152 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Library *
|
||||
;* *
|
||||
;* File Name : PAGFAULT.ASM *
|
||||
;* *
|
||||
;* Programmer : Julio R Jerez *
|
||||
;* *
|
||||
;* Date : April 25,1995 *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;
|
||||
; Here are prototypes for the routines defined within this module:
|
||||
; VOID Install_Page_Fault_Handle (void) ;
|
||||
;
|
||||
; ----------------------------------------------------------------
|
||||
|
||||
IDEAL ; the product runs in ideal mode
|
||||
P386 ; use 386 real mode instructions
|
||||
MODEL USE32 FLAT
|
||||
LOCALS ?? ; ?? is the symbol for a local
|
||||
WARN ; generate all warnings we can
|
||||
JUMPS ; optimize jumps if possible
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Make some general equates for easy compatability
|
||||
;---------------------------------------------------------------------------
|
||||
DPMI_INTR EQU 31h
|
||||
PAGE_FAULT equ 0eh
|
||||
RESET_VIDEO_MODE equ -1
|
||||
|
||||
GLOBAL C Install_Page_Fault_Handle : NEAR
|
||||
GLOBAL C Set_Video_Mode : NEAR
|
||||
GLOBAL C Remove_Mouse : NEAR
|
||||
GLOBAL C Remove_Keyboard_Interrupt : NEAR
|
||||
GLOBAL C Remove_Timer_Interrupt : NEAR
|
||||
|
||||
DATASEG
|
||||
Old_Page_Fault_handle DF ?
|
||||
Page_Fault_SS DD ?
|
||||
Page_Fault_ESP DD ?
|
||||
|
||||
CODESEG
|
||||
;***************************************************************************
|
||||
;* INSTALL_PAGE_FAULT_HANDLE -- Installs new page fault handle *
|
||||
;* This function will install a new page fault handle *
|
||||
;* so in the event that we have a program crash thi handle will *
|
||||
;* remove all interrupts and then will chain to the default Page *
|
||||
;* Fault handle *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* PROTO: VOID Install_Page_Fault_Handle( void); *
|
||||
;* *
|
||||
;* HISTORY: 04/25/96 Created *
|
||||
;*=========================================================================*
|
||||
PROC Install_Page_Fault_Handle C NEAR
|
||||
USES eax,ebx,ecx,edx,esi,edi
|
||||
|
||||
mov eax,0202h ; get address of exception handle
|
||||
mov bl,PAGE_FAULT
|
||||
int DPMI_INTR
|
||||
jc ??exit ; not action is taken
|
||||
|
||||
; save addrees of default handle
|
||||
mov [dword ptr Old_Page_Fault_handle],edx
|
||||
mov [word ptr Old_Page_Fault_handle+4],cx
|
||||
|
||||
; redirect default handle to a new Page Fault Handle
|
||||
mov eax,0203h
|
||||
mov bl,PAGE_FAULT
|
||||
mov cx,cs
|
||||
lea edx,[Page_Fault_Handle]
|
||||
int DPMI_INTR
|
||||
|
||||
??exit:
|
||||
ret
|
||||
ENDP Install_Page_Fault_Handle
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* PAGE_FAULT_HANDLE -- This *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* HISTORY: 04/25/96 Created *
|
||||
;*=========================================================================*
|
||||
PROC Page_Fault_Handle far
|
||||
|
||||
; preserve used registers
|
||||
push eax
|
||||
push ebx
|
||||
; save Page Fault satck frame
|
||||
mov ax,ss
|
||||
mov [Page_Fault_SS],eax
|
||||
mov [Page_Fault_ESP],esp
|
||||
|
||||
; retrieve application original stack frame
|
||||
mov eax , [ esp + ( 6 + 2 ) * 4 ]
|
||||
mov ebx , [ esp + ( 7 + 2 ) * 4 ]
|
||||
mov ss , bx
|
||||
mov esp , eax
|
||||
|
||||
; set video mode to standard text mode
|
||||
push RESET_VIDEO_MODE
|
||||
call Set_Video_Mode
|
||||
pop eax
|
||||
call Remove_Mouse
|
||||
call Remove_Keyboard_Interrupt
|
||||
call Remove_Timer_Interrupt
|
||||
|
||||
; restore Page Fault stack frame
|
||||
mov eax,[Page_Fault_SS]
|
||||
mov ss , ax
|
||||
mov esp, [Page_Fault_ESP]
|
||||
|
||||
; restore used registers and chain to default Page Fault Handle
|
||||
pop ebx
|
||||
pop eax
|
||||
jmp [fword Old_Page_Fault_handle]
|
||||
|
||||
ENDP Page_Fault_Handle
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* End of File. *
|
||||
;***************************************************************************
|
||||
END
|
||||
410
WIN32LIB/SRCDEBUG/PAL.ASM
Normal file
410
WIN32LIB/SRCDEBUG/PAL.ASM
Normal file
@@ -0,0 +1,410 @@
|
||||
;
|
||||
; 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 <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
;***************************************************************************
|
||||
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Project Name : Westwood Library *
|
||||
;* *
|
||||
;* File Name : PAL.ASM *
|
||||
;* *
|
||||
;* Programmer : Joe L. Bostic *
|
||||
;* *
|
||||
;* Start Date : May 30, 1992 *
|
||||
;* *
|
||||
;* Last Update : April 27, 1994 [BR] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Set_Palette_Range -- Sets changed values in the palette. *
|
||||
;* Bump_Color -- adjusts specified color in specified palette *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
;********************** Model & Processor Directives ************************
|
||||
IDEAL
|
||||
P386
|
||||
MODEL USE32 FLAT
|
||||
|
||||
|
||||
;include "keyboard.inc"
|
||||
FALSE = 0
|
||||
TRUE = 1
|
||||
|
||||
;****************************** Declarations ********************************
|
||||
GLOBAL C Set_Palette_Range:NEAR
|
||||
GLOBAL C Bump_Color:NEAR
|
||||
GLOBAL C CurrentPalette:BYTE:768
|
||||
GLOBAL C PaletteTable:byte:1024
|
||||
|
||||
|
||||
;********************************** Data ************************************
|
||||
LOCALS ??
|
||||
|
||||
DATASEG
|
||||
|
||||
CurrentPalette DB 768 DUP(255) ; copy of current values of DAC regs
|
||||
PaletteTable DB 1024 DUP(0)
|
||||
|
||||
IFNDEF LIB_EXTERNS_RESOLVED
|
||||
VertBlank DW 0 ; !!!! this should go away
|
||||
ENDIF
|
||||
|
||||
|
||||
;********************************** Code ************************************
|
||||
CODESEG
|
||||
|
||||
|
||||
|
||||
IF 1
|
||||
;***************************************************************************
|
||||
;* SET_PALETTE_RANGE -- Sets a palette range to the new pal *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* PROTO: *
|
||||
;* *
|
||||
;* WARNINGS: This routine is optimized for changing a small number of *
|
||||
;* colors in the palette.
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 03/07/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
PROC Set_Palette_Range C NEAR
|
||||
ARG palette:DWORD
|
||||
|
||||
GLOBAL Set_DD_Palette_:near
|
||||
GLOBAL Wait_Vert_Blank_:near
|
||||
|
||||
pushad
|
||||
mov esi,[palette]
|
||||
mov ecx,768/4
|
||||
mov edi,offset CurrentPalette
|
||||
cld
|
||||
rep movsd
|
||||
;call Wait_Vert_Blank_
|
||||
mov eax,[palette]
|
||||
call Set_DD_Palette_
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
ifdef NOT_FOR_WIN95
|
||||
USES eax,ebx,ecx,edx,edi,esi
|
||||
|
||||
cld
|
||||
|
||||
;*=================================================================*/
|
||||
;* Set up pointers to begin making palette comparison */
|
||||
;*=================================================================*/
|
||||
mov esi, [palette]
|
||||
mov edi, OFFSET CurrentPalette
|
||||
mov ebx, OFFSET PaletteTable
|
||||
mov ecx, 0
|
||||
|
||||
??loop_top:
|
||||
mov eax,[esi] ; read a dword from palette source
|
||||
mov edx,[edi] ; read a dword from compare palette
|
||||
and eax,00FFFFFFh ; palette entrys are only 3 bytes
|
||||
and edx,00FFFFFFh ; long so and of extra
|
||||
cmp eax,edx ; if they are not the same then
|
||||
jne ??set_table ; add them into the table
|
||||
add esi,3
|
||||
add edi,3
|
||||
inc cl ; adjust to next palette entry
|
||||
jnz ??loop_top ; if we dont wrap to zero we have more
|
||||
jmp ??set_pal ; so now go set the palette
|
||||
??set_table:
|
||||
shl eax,8 ; shift bgr value up register
|
||||
mov al,cl ; store which palette entry num
|
||||
mov [ebx],eax
|
||||
add ebx,4
|
||||
movsw ; copy the three gun values into
|
||||
movsb ; the shadow palette. Use movsb
|
||||
inc cl ; adjust to next palette entry
|
||||
jnz ??loop_top ; if we dont wrap to zero we have more
|
||||
|
||||
??set_pal:
|
||||
mov esi,ebx
|
||||
mov ebx,OFFSET PaletteTable
|
||||
sub esi,ebx ; if ebx didn't change there
|
||||
jz ??exit ; is nothing to set
|
||||
shr esi,2 ; find how many entrys
|
||||
|
||||
mov eax,[ebx]
|
||||
|
||||
movzx ecx,al ; we are currently on entry 0
|
||||
add ebx,4
|
||||
|
||||
; Tell DAC of the color gun to start setting.
|
||||
mov edx,03C8h
|
||||
out dx,al ; First color set.
|
||||
|
||||
; Set the colors only during a VSync.
|
||||
mov edx,03DAh ; CRTC register.
|
||||
|
||||
push ebx
|
||||
mov bx,[VertBlank]
|
||||
and bl,001h
|
||||
shl bl,3
|
||||
|
||||
??in_vbi:
|
||||
in al,dx ; read CRTC status
|
||||
and al,008h ; only vertical sync bit
|
||||
xor al,bl
|
||||
je ??in_vbi ; in vertical sync
|
||||
|
||||
??out_vbi:
|
||||
in al,dx ; read CRTC status
|
||||
and al,008h ; only vertical sync bit
|
||||
xor al,bl
|
||||
jne ??out_vbi ; not in vertical sync
|
||||
pop ebx
|
||||
; Update the DAC data register.
|
||||
mov dx,03C9h
|
||||
|
||||
;**************** Time Critical Section Start ******************
|
||||
cli
|
||||
??loop:
|
||||
shr eax,8 ; shift down the red gun value
|
||||
out dx,al ; write it to the video card
|
||||
jmp $ + 2 ; force cache to flush, to create a time
|
||||
shr eax,8 ; shift down the blue gun value
|
||||
out dx,al ; write it to the video card
|
||||
jmp $ + 2 ; force cache to flush, to create a time
|
||||
shr eax,8 ; shift down the blue gun value
|
||||
out dx,al ; write the green value to video card
|
||||
jmp $ + 2 ; force cache to flush, to create a time
|
||||
inc ecx ; move edx to next palette entry
|
||||
|
||||
mov eax,[ebx] ; get next value to set
|
||||
add ebx,4 ; and post increment the palette value
|
||||
cmp al,cl ; check if DAC position already correct
|
||||
je ??correct_pos
|
||||
|
||||
mov edx,03C8h ; Tell DAC of the color gun to start setting.
|
||||
out dx,al ; First color set.
|
||||
mov dx,03C9h
|
||||
|
||||
??correct_pos:
|
||||
dec esi
|
||||
jnz ??loop
|
||||
sti
|
||||
;***************** Time Critical Section End *******************
|
||||
??exit:
|
||||
ret
|
||||
endif ;NOT_FOR_WIN95
|
||||
|
||||
ENDP Set_Palette_Range
|
||||
ELSE
|
||||
;***************************************************************************
|
||||
;* Set_Palette_Range -- Sets changed values in the palette. *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* VOID *palette - pointer to the new palette. *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* none *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/25/1994 SKB : Created. *
|
||||
;* 04/27/1994 BR : Converted to 32-bit *
|
||||
;*=========================================================================*
|
||||
; VOID cdecl Set_Palette_Range(VOID *palette);
|
||||
PROC Set_Palette_Range C NEAR
|
||||
USES eax,ebx,ecx,edx,edi,esi
|
||||
ARG palette:DWORD
|
||||
LOCAL remain:DWORD ; 32-bit: converted to LONG
|
||||
|
||||
cld
|
||||
|
||||
mov bx,[VertBlank]
|
||||
and bl,001h
|
||||
shl bl,3
|
||||
|
||||
; Make a copy of the palette passed in.
|
||||
mov edi,OFFSET CurrentPalette
|
||||
mov esi,[palette]
|
||||
mov [remain],768
|
||||
|
||||
; Search for differences between the current palette and the
|
||||
; new palette. When a difference is found, output a block
|
||||
; of color registers and keep scanning.
|
||||
??bodyloop:
|
||||
mov ecx,[remain]
|
||||
|
||||
repe cmpsb ; Search for differences.
|
||||
je short ??exit
|
||||
dec esi
|
||||
dec edi
|
||||
inc ecx
|
||||
|
||||
mov edx,0 ; clear EDX
|
||||
mov eax,ecx
|
||||
mov ecx,3
|
||||
div ecx ; EAX = # of colors to set, EDX = Fraction.
|
||||
or edx,edx
|
||||
jz short ??nofrac
|
||||
neg edx
|
||||
add edx,3 ; Back offset skip needed.
|
||||
inc eax ; Fractional color rounds up to whole color to set.
|
||||
??nofrac:
|
||||
|
||||
; Set CX to be the number of color guns to set.
|
||||
mov ecx,eax ; Colors * 3 bytes per color.
|
||||
add ecx,eax
|
||||
add ecx,eax
|
||||
|
||||
; Chop this DAC dump short if necessary in order to reduce
|
||||
; sparkling.
|
||||
mov [remain],0
|
||||
cmp ecx,86*3 ; Number of color guns to set per vert retrace
|
||||
jbe short ??ok
|
||||
sub ecx,86*3
|
||||
mov [remain],ecx
|
||||
mov ecx,86*3
|
||||
??ok:
|
||||
|
||||
; Adjust the palette offsets back to point to the RED color gun.
|
||||
sub esi,edx
|
||||
sub edi,edx
|
||||
|
||||
; Determine the color number to start setting.
|
||||
neg eax
|
||||
add eax,256 ; AX = Color to start setting (0..255).
|
||||
|
||||
; Tell DAC of the color gun to start setting.
|
||||
mov edx,03C8h
|
||||
out dx,al ; First color set.
|
||||
|
||||
; Set the colors only during a VSync.
|
||||
mov edx,03DAh ; CRTC register.
|
||||
|
||||
??in_vbi:
|
||||
in al,dx ; read CRTC status
|
||||
and al,008h ; only vertical sync bit
|
||||
xor al,bl
|
||||
je ??in_vbi ; in vertical sync
|
||||
|
||||
??out_vbi:
|
||||
in al,dx ; read CRTC status
|
||||
and al,008h ; only vertical sync bit
|
||||
xor al,bl
|
||||
jne ??out_vbi ; not in vertical sync
|
||||
|
||||
;??wait:
|
||||
; in al,dx
|
||||
; test al,01000b
|
||||
; jnz ??wait
|
||||
|
||||
;??retrace:
|
||||
; in al,dx
|
||||
; test al,01000b
|
||||
; jz ??retrace
|
||||
|
||||
; Update the DAC data register.
|
||||
mov dx,03C9h
|
||||
|
||||
;**************** Time Critical Section Start ******************
|
||||
pushf
|
||||
cli
|
||||
??loop:
|
||||
lodsb
|
||||
stosb
|
||||
out dx,al
|
||||
jmp $ + 2 ; force cache to flush, to create a time
|
||||
; delay to give DAC time to get value
|
||||
loop ??loop
|
||||
popf
|
||||
;***************** Time Critical Section End *******************
|
||||
|
||||
cmp [remain],0
|
||||
jnz ??bodyloop
|
||||
|
||||
??exit:
|
||||
ret
|
||||
|
||||
ENDP Set_Palette_Range
|
||||
ENDIF
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* Bump_Color -- adjusts specified color in specified palette *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* VOID *palette - palette to modify *
|
||||
;* WORD changable - color # to change *
|
||||
;* WORD target - color to bend toward *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 04/27/1994 BR : Converted to 32-bit. *
|
||||
;*=========================================================================*
|
||||
; BOOL cdecl Bump_Color(VOID *palette, WORD changable, WORD target);
|
||||
PROC Bump_Color C NEAR
|
||||
USES ebx,ecx,edi,esi
|
||||
ARG pal:DWORD, color:WORD, desired:WORD
|
||||
LOCAL changed:WORD ; Has palette changed?
|
||||
|
||||
mov edi,[pal] ; Original palette pointer.
|
||||
mov esi,edi
|
||||
mov eax,0
|
||||
mov ax,[color]
|
||||
add edi,eax
|
||||
add edi,eax
|
||||
add edi,eax ; Offset to changable color.
|
||||
mov ax,[desired]
|
||||
add esi,eax
|
||||
add esi,eax
|
||||
add esi,eax ; Offset to target color.
|
||||
|
||||
mov [changed],FALSE ; Presume no change.
|
||||
mov ecx,3 ; Three color guns.
|
||||
|
||||
; Check the color gun.
|
||||
??colorloop:
|
||||
mov al,[BYTE PTR esi]
|
||||
sub al,[BYTE PTR edi] ; Carry flag is set if subtraction needed.
|
||||
jz short ??gotit
|
||||
mov [changed],TRUE
|
||||
inc [BYTE PTR edi] ; Presume addition.
|
||||
jnc short ??gotit ; oops, subtraction needed so dec twice.
|
||||
dec [BYTE PTR edi]
|
||||
dec [BYTE PTR edi]
|
||||
??gotit:
|
||||
inc edi
|
||||
inc esi
|
||||
loop ??colorloop
|
||||
|
||||
mov ax,[changed]
|
||||
ret
|
||||
|
||||
ENDP Bump_Color
|
||||
|
||||
END
|
||||
|
||||
;*************************** End of pal.asm ********************************
|
||||
|
||||
382
WIN32LIB/SRCDEBUG/PALETTE.CPP
Normal file
382
WIN32LIB/SRCDEBUG/PALETTE.CPP
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : WWLIB *
|
||||
* *
|
||||
* File Name : PALETTE.C *
|
||||
* *
|
||||
* Programmer : BILL STOKES *
|
||||
* *
|
||||
* Start Date : 6/20/91 *
|
||||
* *
|
||||
* Last Update : August 2, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Note: This module contains dependencies upon the video system, *
|
||||
* specifically Get_Video_Mode(). *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Set_Palette -- sets the current palette *
|
||||
* Set_Palette_Color -- Set a color number in a palette to the data. *
|
||||
* Fade_Palette_To -- Fades the current palette into another *
|
||||
* Determine_Bump_Rate -- determines desired bump rate for fading *
|
||||
* Bump_Palette -- increments the palette one step, for fading *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/*
|
||||
********************************* Includes **********************************
|
||||
*/
|
||||
#include <mem.h>
|
||||
#include "wwstd.h"
|
||||
#include "palette.h"
|
||||
#include "timer.h"
|
||||
|
||||
/*
|
||||
********************************* Constants *********************************
|
||||
*/
|
||||
|
||||
/*
|
||||
********************************** Globals **********************************
|
||||
*/
|
||||
extern "C" extern unsigned char CurrentPalette[]; /* in pal.asm */
|
||||
|
||||
/*
|
||||
******************************** Prototypes *********************************
|
||||
*/
|
||||
|
||||
PRIVATE void __cdecl Determine_Bump_Rate(void *palette, int delay, short *ticks, short *rate);
|
||||
PRIVATE BOOL __cdecl Bump_Palette(void *palette1, unsigned int step);
|
||||
|
||||
/*
|
||||
******************************** Code *********************************
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
* Set_Palette -- sets the current palette *
|
||||
* *
|
||||
* INPUT: *
|
||||
* void *palette - palette to set *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/25/1994 SKB : Created. *
|
||||
* 04/27/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
void __cdecl Set_Palette(void *palette)
|
||||
{
|
||||
|
||||
#if(IBM)
|
||||
Set_Palette_Range(palette);
|
||||
#else
|
||||
Copy_Palette(palette,CurrentPalette);
|
||||
LoadRGB4(&Main_Screen->ViewPort,palette,32L);
|
||||
LoadRGB4(AltVPort,palette,32L);
|
||||
#endif
|
||||
|
||||
} /* end of Set_Palette */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Set_Palette_Color -- Set a color number in a palette to the data. *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* void *palette - palette to set color in *
|
||||
* int color - which color index to set *
|
||||
* void *data - RGB data for color *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/25/1994 SKB : Created. *
|
||||
* 04/27/1994 BR : Converted to 32-bit *
|
||||
*=========================================================================*/
|
||||
void __cdecl Set_Palette_Color(void *palette, int color, void *data)
|
||||
{
|
||||
/*
|
||||
---------------------- Return if 'palette' is NULL -----------------------
|
||||
*/
|
||||
if (!palette) return;
|
||||
|
||||
/*
|
||||
------------------- Change the color & set the palette -------------------
|
||||
*/
|
||||
#if(IBM)
|
||||
memcpy(&((unsigned char *)palette)[color * RGB_BYTES], data, RGB_BYTES);
|
||||
Set_Palette_Range(palette);
|
||||
#else
|
||||
palette[color] = *(unsigned short*)data;
|
||||
Set_Palette(palette);
|
||||
#endif
|
||||
|
||||
} /* end of Set_Palette */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Fade_Palette_To -- Fades the current palette into another *
|
||||
* *
|
||||
* This will allow the palette to fade from current palette into the *
|
||||
* palette that was passed in. This can be used to fade in and fade out. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* char *palette1 - this is the palette to fade to. *
|
||||
* unsigned int delay - fade with this timer count down *
|
||||
* void *callback - user-defined callback function *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/20/1991 BS : Created. *
|
||||
*=========================================================================*/
|
||||
void Fade_Palette_To(void *palette1, unsigned int delay, void (*callback)() )
|
||||
{
|
||||
BOOL changed; // Flag that palette has changed this tick.
|
||||
short jump; // Gun values to jump per palette set.
|
||||
unsigned long timer; // Tick count timer used for timing.
|
||||
short ticksper; // The ticks (fixed point) per bit jump.
|
||||
int tickaccum;
|
||||
|
||||
|
||||
extern void (*cb_ptr)(void); // callback function pointer
|
||||
|
||||
// (void *)cb_ptr = callback;
|
||||
cb_ptr = callback;
|
||||
|
||||
/*
|
||||
---------------------- Return if 'palette1' is NULL ----------------------
|
||||
*/
|
||||
if (!palette1)
|
||||
return;
|
||||
|
||||
/*
|
||||
--------------------------- Get the bump rate ----------------------------
|
||||
*/
|
||||
Determine_Bump_Rate(palette1, delay, &ticksper, &jump);
|
||||
|
||||
tickaccum = 0; // init accumulated elapsed time
|
||||
timer = TickCount.Time(); // timer = current time
|
||||
do {
|
||||
changed = FALSE;
|
||||
|
||||
tickaccum += ticksper; // tickaccum = time of next change * 256
|
||||
timer += (tickaccum >> 8); // timer = time of next change (rounded)
|
||||
tickaccum &= 0x0FF; // shave off high byte, keep roundoff bits
|
||||
|
||||
changed = Bump_Palette(palette1, jump); // increment palette
|
||||
|
||||
/*
|
||||
.................. Wait for time increment to elapse ..................
|
||||
*/
|
||||
if (changed) {
|
||||
while (TickCount.Time() < timer) {
|
||||
/*
|
||||
................. Update callback while waiting .................
|
||||
*/
|
||||
if (callback) {
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
Sound_Callback(); // should be removed!
|
||||
#endif
|
||||
(*cb_ptr)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if LIB_EXTERNS_RESOLVED
|
||||
Sound_Callback(); // should be removed!
|
||||
#endif
|
||||
if (callback) {
|
||||
(*cb_ptr)();
|
||||
}
|
||||
} while (changed);
|
||||
|
||||
} /* end of Fade_Palette_To */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Determine_Bump_Rate -- determines desired bump rate for fading *
|
||||
* *
|
||||
* INPUT: *
|
||||
* unsigned char *palette - palette to fade to *
|
||||
* int delay - desired time delay in 60ths of a second *
|
||||
* short *ticks - output: loop ticks per color jump *
|
||||
* short *rate - output: color gun increment rate *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* none *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/27/1994 BR : Converted to 32-bit *
|
||||
* 08/02/1994 SKB : Made private *
|
||||
*=========================================================================*/
|
||||
PRIVATE void __cdecl Determine_Bump_Rate(void *palette, int delay, short *ticks,
|
||||
short *rate)
|
||||
{
|
||||
int gun1; // Palette 1 gun value.
|
||||
int gun2; // Palette 2 gun value.
|
||||
int diff; // Maximum color gun difference.
|
||||
int tp; // Temporary tick accumulator.
|
||||
int index; // Color gun working index.
|
||||
long t; // Working tick intermediate value.
|
||||
int adiff; // Absolute difference between guns.
|
||||
|
||||
/*
|
||||
------------------------ Find max gun difference -------------------------
|
||||
*/
|
||||
diff = 0;
|
||||
for (index = 0; index < PALETTE_BYTES; index++) {
|
||||
gun1 = ((unsigned char *)palette)[index];
|
||||
gun2 = CurrentPalette[index];
|
||||
adiff = ABS(gun1-gun2);
|
||||
diff = MAX(diff, adiff);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
ticks = (total time delay ) / (max gun diff)
|
||||
The value is computed based on (delay * 256), for fixed-point math;
|
||||
the lower bits represent the leftover from the division; 'ticks' is
|
||||
returned still shifted, so the low bits can be used to accumulate the
|
||||
time more accurately; the caller must shift the accumulated value down
|
||||
8 bits to determine the actual elapsed time!
|
||||
------------------------------------------------------------------------*/
|
||||
t = ((long)delay) << 8;
|
||||
if (diff) {
|
||||
t /= diff;
|
||||
t = MIN((long)t, (long)0x7FFF);
|
||||
}
|
||||
*ticks = (short)t;
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Adjust the color gun rate value if the time to fade is faster than can
|
||||
reasonably be performed given the palette change, ie if (ticks>>8)==0,
|
||||
and thus less than 1/60 of a second
|
||||
------------------------------------------------------------------------*/
|
||||
tp = *ticks;
|
||||
*rate = 1;
|
||||
while (*rate <= diff && *ticks < 256) {
|
||||
*ticks += tp;
|
||||
*rate += 1;
|
||||
}
|
||||
|
||||
} /* end of Determine_Bump_Rate */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Bump_Palette -- increments the palette one step, for fading *
|
||||
* *
|
||||
* INPUT: *
|
||||
* palette1 - palette to fade towards *
|
||||
* step - max step amount, determined by Determine_Bump_Rate *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* FALSE = no change, TRUE = changed *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/27/1994 BR : Created. *
|
||||
* 08/02/1994 SKB : Made private *
|
||||
*=========================================================================*/
|
||||
#if(IBM)
|
||||
PRIVATE BOOL __cdecl Bump_Palette(void *palette1, unsigned int step)
|
||||
{
|
||||
BOOL changed=FALSE; // Flag that palette has changed this tick.
|
||||
int index; // Index to DAC register gun.
|
||||
int gun1,gun2; // Palette 1 gun value.
|
||||
unsigned char palette[PALETTE_BYTES]; // copy of current palette
|
||||
|
||||
/*
|
||||
---------------------- Return if 'palette1' is NULL ----------------------
|
||||
*/
|
||||
if (!palette1)
|
||||
return (FALSE);
|
||||
|
||||
|
||||
/*
|
||||
------------------------ Copy the current palette ------------------------
|
||||
*/
|
||||
memcpy(palette, CurrentPalette, 768);
|
||||
|
||||
/*
|
||||
----------------------- Loop through palette bytes -----------------------
|
||||
*/
|
||||
for (index = 0; index < PALETTE_BYTES; index++) {
|
||||
gun1 = ((unsigned char *)palette1)[index];
|
||||
gun2 = palette[index];
|
||||
|
||||
/*
|
||||
............. If the colors match, go on to the next one ..............
|
||||
*/
|
||||
if (gun1 == gun2) continue;
|
||||
|
||||
changed = TRUE;
|
||||
|
||||
/*
|
||||
.................. Increment current palette's color ..................
|
||||
*/
|
||||
if (gun2 < gun1) {
|
||||
gun2 += step;
|
||||
gun2 = MIN(gun2, gun1); // make sure we didn't overshoot it
|
||||
}
|
||||
/*
|
||||
.................. Decrement current palette's color ..................
|
||||
*/
|
||||
else {
|
||||
gun2 -= step;
|
||||
gun2 = MAX(gun2, gun1); // make sure we didn't overshoot it
|
||||
}
|
||||
|
||||
palette[index] = (unsigned char)gun2;
|
||||
}
|
||||
|
||||
/*
|
||||
----------------- Set current palette to the new palette -----------------
|
||||
*/
|
||||
if (changed) {
|
||||
Set_Palette(&palette[0]);
|
||||
}
|
||||
|
||||
return (changed);
|
||||
|
||||
} /* end of Bump_Palette */
|
||||
|
||||
#else
|
||||
|
||||
/* This is already implemented in asm on the Amiga */
|
||||
|
||||
#endif
|
||||
|
||||
void (*cb_ptr)(void); // callback function pointer
|
||||
|
||||
/**************************** End of palette.cpp ***************************/
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user