Initial commit of Command & Conquer Red Alert source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:15:05 +00:00
parent b685cea758
commit 5e733d5dcc
2082 changed files with 797727 additions and 0 deletions

View 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(BYTE *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 ***************************/

183
WWFLAT32/PALETTE/MAKEFILE Normal file
View File

@@ -0,0 +1,183 @@
#
# 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 .LIB makefile *
#* *
#* File Name : MAKEFILE *
#* *
#* Programmer : Julio R. Jerez *
#* *
#* Start Date : January 27, 1995 *
#* *
#* *
#*-------------------------------------------------------------------------*
#* *
#* Required environment variables: *
#* WWFLAT = your root WWFLAT path *
#* WWVCS = root directory for wwlib version control archive *
#* WATCOM = your Watcom installation path *
#* *
#* Required changes to makefile: *
#* PROJ_NAME = name of the library you're building *
#* OBJECTS = list of objects in your library *
#* *
#* Optional changes to makefile: *
#* PROJ_DIR = full pathname of your working directory *
#* .path.xxx = full pathname where various file types live *
#* *
#***************************************************************************
#---------------------------------------------------------------------------
# Verify user's environment
#---------------------------------------------------------------------------
!ifndef %WWFLAT
!error WWFLAT Environment var not configured.
!endif
!ifndef %WWVCS
!error WWVCS Environment var not configured.
!endif
!ifndef %WATCOM
!error WATCOM Environment var not configured.
!endif
#===========================================================================
# User-defined section: the user should tailor this section for each project
#===========================================================================
PROJ_NAME = palette
PROJ_DIR = $(%WWFLAT)\$(PROJ_NAME)
LIB_DIR = $(%WWFLAT)\lib
!include $(%WWFLAT)\project.cfg
#---------------------------------------------------------------------------
# Project-dependent variables
#---------------------------------------------------------------------------
OBJECTS = &
loadpal.obj &
morphpal.obj &
palette.obj &
pal.obj
#---------------------------------------------------------------------------
# Path macros: one path for each file type.
# These paths are used to tell make where to find/put each file type.
#---------------------------------------------------------------------------
.asm: $(PROJ_DIR)
.c: $(PROJ_DIR)
.cpp: $(PROJ_DIR)
.h: $(PROJ_DIR)
.obj: $(PROJ_DIR)
.lib: $(%WWFLAT)\lib
.exe: $(PROJ_DIR)
#===========================================================================
# Pre-defined section: there should be little need to modify this section.
#===========================================================================
#---------------------------------------------------------------------------
# Tools/commands
#---------------------------------------------------------------------------
C_CMD = wcc386
CPP_CMD = wpp386
LIB_CMD = wlib
LINK_CMD = wlink
ASM_CMD = tasm32
#---------------------------------------------------------------------------
# Include & library paths
# If LIB & INCLUDE are already defined, they are used in addition to the
# WWLIB32 lib & include; otherwise, they're constructed from
# BCDIR & TNTDIR
#---------------------------------------------------------------------------
LIBPATH = $(%WWFLAT)\LIB;$(%WATCOM)\LIB
INCLUDEPATH = $(%WWFLAT)\INCLUDE;$(%WATCOM)\H
#---------------------------------------------------------------------------
# Implicit rules
# Compiler:
# ($< = full dependent with path)
# Assembler:
# output obj's are constructed from .obj: & the $& macro
# ($< = full dependent with path)
# tasm's cfg file is not invoked as a response file.
#---------------------------------------------------------------------------
.c.obj: $(%WWFLAT)\project.cfg .AUTODEPEND
$(C_CMD) $(CC_CFG) $<
.cpp.obj: $(%WWFLAT)\project.cfg .AUTODEPEND
$(CPP_CMD) $(CC_CFG) $<
.asm.obj: $(%WWFLAT)\project.cfg
$(ASM_CMD) $(ASM_CFG) $<
#---------------------------------------------------------------------------
# Default target: configuration files & library (in that order)
#---------------------------------------------------------------------------
all: $(LIB_DIR)\$(PROJ_NAME).lib .SYMBOLIC
#---------------------------------------------------------------------------
# Build the library
# The original library is deleted by the librarian
# Lib objects & -+ commands are constructed by substituting within the
# $^@ macro (which expands to all target dependents, separated with
# spaces)
# Tlib's cfg file is not invoked as a response file.
# All headers & source files are copied into WWFLAT\SRCDEBUG, for debugging
#---------------------------------------------------------------------------
$(LIB_DIR)\$(PROJ_NAME).lib: $(OBJECTS) objects.lbc
copy *.h $(%WWFLAT)\include
copy *.inc $(%WWFLAT)\include
copy *.cpp $(%WWFLAT)\srcdebug
copy *.asm $(%WWFLAT)\srcdebug
$(LIB_CMD) $(LIB_CFG) $^@ @objects.lbc
#---------------------------------------------------------------------------
# Objects now have a link file which is NOT generated everytime. Instead
# it just has its own dependacy rule.
#---------------------------------------------------------------------------
objects.lbc : $(OBJECTS)
%create $^@
for %index in ($(OBJECTS)) do %append $^@ +%index
#---------------------------------------------------------------------------
# Create the test directory and make it.
#---------------------------------------------------------------------------
test:
mkdir test
cd test
copy $(%WWVCS)\$(PROJ_NAME)\test\vcs.cfg
update
wmake
cd ..
#**************************** End of makefile ******************************

View File

@@ -0,0 +1,174 @@
/*
** 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 "video.h"
#include "palette.h"
#include "timer.h"
/*
********************************* Constants *********************************
*/
#define SCALE(a,b,c) (((((LONG)(a)<<8) / (LONG)(b) ) * (ULONG)(c)) >>8)
/*
********************************** Globals **********************************
*/
/*
******************************** Prototypes *********************************
*/
PRIVATE WORD cdecl Palette_To_Palette(VOID *src_palette, VOID *dst_palette, ULONG current_time, ULONG delay);
/***************************************************************************
* Morph_Palette -- morphs a palette from source to destination *
* *
* INPUT: *
* VOID *src_pal - starting palette *
* VOID *dst_pal - ending palette *
* UWORD 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, UWORD delay,
VOID (*callback) (VOID) )
{
WORD result;
ULONG pal_start = TickCount.Time();
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), (ULONG)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: WORD 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 WORD cdecl Palette_To_Palette(VOID *src_palette, VOID *dst_palette,
ULONG current_time, ULONG delay)
{
BYTE colour;
BYTE diff;
WORD chgval;
WORD lp;
WORD change;
static BYTE palette[768];
/*======================================================================*/
/* 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 = ( ( ((BYTE *)dst_palette)[lp] & 63) -
( ((BYTE *)src_palette)[lp] & 63) );
if (diff)
change = TRUE;
chgval = SCALE(diff, delay, current_time);
colour = ( ((BYTE *)src_palette)[lp] & 63) + chgval;
}
else {
colour = ((BYTE *)dst_palette)[lp] & 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 ***************************/


388
WWFLAT32/PALETTE/PAL.ASM Normal file
View 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 : 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"
;****************************** Declarations ********************************
GLOBAL Set_Palette_Range:NEAR
GLOBAL Bump_Color:NEAR
GLOBAL CurrentPalette:BYTE:768
GLOBAL 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
USES eax,ebx,ecx,edx,edi,esi
ARG palette:DWORD
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
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 ********************************


View File

@@ -0,0 +1,392 @@
/*
** 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 "video.h"
#include "palette.h"
#include "timer.h"
/*
********************************* Constants *********************************
*/
/*
********************************** Globals **********************************
*/
extern "C" extern UBYTE CurrentPalette[]; /* in pal.asm */
/*
******************************** Prototypes *********************************
*/
PRIVATE VOID cdecl Determine_Bump_Rate(VOID *palette, WORD delay, WORD *ticks, WORD *rate);
PRIVATE BOOL cdecl Bump_Palette(VOID *palette1, UWORD 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 *
* WORD 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, WORD color, VOID *data)
{
/*
---------------------- Return if 'palette' is NULL -----------------------
*/
if (!palette) return;
/*
------------------- Change the color & set the palette -------------------
*/
#if(IBM)
memcpy(&((UBYTE *)palette)[color * RGB_BYTES], data, RGB_BYTES);
Set_Palette_Range(palette);
#else
palette[color] = *(UWORD*)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: *
* BYTE *palette1 - this is the palette to fade to. *
* UWORD 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, UWORD delay, VOID (*callback)() )
{
BOOL changed; // Flag that palette has changed this tick.
WORD jump; // Gun values to jump per palette set.
ULONG timer; // Tick count timer used for timing.
WORD ticksper; // The ticks (fixed point) per bit jump.
WORD tickaccum;
VOID (*cb_ptr)(VOID); // callback function pointer
// (VOID *)cb_ptr = callback;
cb_ptr = callback;
/*
---------------------- Return if 'palette1' is NULL ----------------------
*/
if (!palette1)
return;
/*
--------------------- Fading only supported in MCGA ----------------------
*/
if (Get_Video_Mode() != MCGA_MODE) { // was global GraphicMode
Set_Palette(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: *
* UBYTE *palette - palette to fade to *
* WORD delay - desired time delay in 60ths of a second *
* WORD *ticks - output: loop ticks per color jump *
* WORD *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, WORD delay, WORD *ticks,
WORD *rate)
{
WORD gun1; // Palette 1 gun value.
WORD gun2; // Palette 2 gun value.
WORD diff; // Maximum color gun difference.
WORD tp; // Temporary tick accumulator.
WORD index; // Color gun working index.
LONG t; // Working tick intermediate value.
WORD adiff; // Absolute difference between guns.
/*
------------------------ Find max gun difference -------------------------
*/
diff = 0;
for (index = 0; index < PALETTE_BYTES; index++) {
gun1 = ((UBYTE *)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 = (WORD)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, UWORD step)
{
BOOL changed=FALSE; // Flag that palette has changed this tick.
WORD index; // Index to DAC register gun.
WORD gun1,gun2; // Palette 1 gun value.
UBYTE palette[PALETTE_BYTES]; // copy of current palette
/*
---------------------- Return if 'palette1' is NULL ----------------------
*/
if (!palette1)
return (FALSE);
/*
--------------------- Fading only supported in MCGA ----------------------
*/
if (Get_Video_Mode() != MCGA_MODE) { // was global GraphicMode
Set_Palette(palette1);
return (FALSE);
}
/*
------------------------ Copy the current palette ------------------------
*/
memcpy(palette, CurrentPalette, 768);
/*
----------------------- Loop through palette bytes -----------------------
*/
for (index = 0; index < PALETTE_BYTES; index++) {
gun1 = ((UBYTE *)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] = 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
/**************************** End of palette.cpp ***************************/


View 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 : Palette 32bit Library. *
;* *
;* File Name : PALETTE.H *
;* *
;* Programmer : Scott K. Bowen *
;* *
;* Start Date : April 25, 1994 *
;* *
;* Last Update : April 27, 1994 [BRR] *
;* *
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef PALETTE_H
#define PALETTE_H
/*
********************************* Constants *********************************
*/
#define RGB_BYTES 3
#define PALETTE_SIZE 256
#define PALETTE_BYTES 768
/*
******************************** Prototypes *********************************
*/
/*
-------------------------------- Palette.cpp --------------------------------
*/
VOID cdecl Set_Palette(VOID *palette);
VOID cdecl Set_Palette_Color(VOID *palette, WORD color, VOID *data);
VOID Fade_Palette_To(VOID *palette1, UWORD delay, VOID (*callback)() );
/*
-------------------------------- loadpal.cpp --------------------------------
*/
VOID cdecl Load_Palette(BYTE *palette_file_name, VOID *palette_pointer);
/*
------------------------------- morphpal.cpp --------------------------------
*/
VOID cdecl Morph_Palette (VOID *src_palette, VOID *dst_palette, UWORD delay,
VOID *callback);
/*
---------------------------------- pal.asm ----------------------------------
*/
#ifdef __cplusplus
extern "C" {
#endif
extern VOID Set_Palette_Range(VOID *palette);
extern BOOL Bump_Color(VOID *palette, WORD changable, WORD target);
#ifdef __cplusplus
}
#endif
extern "C" extern UBYTE CurrentPalette[]; /* in pal.asm */
#endif // PALETTE_H
/***************************** End of palette.h ****************************/