mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-17 17:00:29 +02:00
Replaced TXTPRNT.ASM with TXTPRNT.CPP from Chronoshift.
This commit is contained in:
@@ -1,520 +0,0 @@
|
||||
;
|
||||
; Copyright 2020 Electronic Arts Inc.
|
||||
;
|
||||
; TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
|
||||
|
||||
; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
||||
; in the hope that it will be useful, but with permitted additional restrictions
|
||||
; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
; distributed with this program. You should have received a copy of the
|
||||
; GNU General Public License along with permitted additional restrictions
|
||||
; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.
|
||||
|
||||
;***************************************************************************
|
||||
;** 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 : TXTPRNT.ASM *
|
||||
;* *
|
||||
;* Programmer : Phil W. Gorrow *
|
||||
;* *
|
||||
;* Start Date : January 17, 1995 *
|
||||
;* *
|
||||
;* Last Update : January 17, 1995 [PWG] *
|
||||
;* *
|
||||
;*-------------------------------------------------------------------------*
|
||||
;* Functions: *
|
||||
;* Buffer_Print -- Assembly text print to a buffer *
|
||||
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
||||
|
||||
;IDEAL
|
||||
;P386
|
||||
;MODEL USE32 FLAT
|
||||
.MODEL FLAT
|
||||
|
||||
|
||||
;INCLUDE "mcgaprim.inc"
|
||||
;INCLUDE ".\gbuffer.inc"
|
||||
|
||||
externdef C Buffer_Print : NEAR
|
||||
|
||||
GraphicViewPort STRUCT
|
||||
GVPOffset DD ? ; offset to virtual viewport
|
||||
GVPWidth DD ? ; width of virtual viewport
|
||||
GVPHeight DD ? ; height of virtual viewport
|
||||
GVPXAdd DD ? ; x mod to get to next line
|
||||
GVPXPos DD ? ; x pos relative to Graphic Buff
|
||||
GVPYPos DD ? ; y pos relative to Graphic Buff
|
||||
GVPPitch DD ? ; modulo of graphic view port
|
||||
GVPBuffPtr DD ? ; ptr to associated Graphic Buff
|
||||
GraphicViewPort ENDS
|
||||
|
||||
|
||||
;*=========================================================================*
|
||||
;* Extern the font pointer which is defined by the font class *
|
||||
;*=========================================================================*
|
||||
extern C FontPtr:DWORD
|
||||
extern C FontXSpacing:DWORD
|
||||
extern C FontYSpacing:DWORD
|
||||
externdef C ColorXlat:byte
|
||||
|
||||
;*=========================================================================*
|
||||
;* Define the necessary equates for structures and bounds checking *
|
||||
;*=========================================================================*
|
||||
; The header of the font file looks like this:
|
||||
; UWORD FontLength; 0
|
||||
; BYTE FontCompress; 2
|
||||
; BYTE FontDataBlocks; 3
|
||||
; UWORD InfoBlockOffset; 4
|
||||
; UWORD OffsetBlockOffset; 6
|
||||
; UWORD WidthBlockOffset; 8
|
||||
; UWORD DataBlockOffset; 10
|
||||
; UWORD HeightOffset; 12
|
||||
; For this reason the following equates have these values:
|
||||
FONTINFOBLOCK EQU 4
|
||||
FONTOFFSETBLOCK EQU 6
|
||||
FONTWIDTHBLOCK EQU 8
|
||||
FONTDATABLOCK EQU 10
|
||||
FONTHEIGHTBLOCK EQU 12
|
||||
|
||||
FONTINFOMAXHEIGHT EQU 4
|
||||
FONTINFOMAXWIDTH EQU 5
|
||||
|
||||
|
||||
;LOCALS ??
|
||||
;*=========================================================================*
|
||||
;* Define the color xlate table in the data segment *
|
||||
;*=========================================================================*
|
||||
;DATASEG
|
||||
.data
|
||||
|
||||
ColorXlat DB 00H,01H,02H,03H,04H,05H,06H,07H
|
||||
DB 08H,09H,0AH,0BH,0CH,0DH,0EH,0FH
|
||||
|
||||
DB 01H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 02H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 03H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 04H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 05H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 06H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 07H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 08H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 09H,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 0AH,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 0BH,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 0CH,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 0DH,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 0EH,00H,00H,00H,00H,00H,00H,00H
|
||||
DB 00H,00H,00H,00H,00H,00H,00H,00H
|
||||
|
||||
DB 0FH
|
||||
|
||||
;CODESEG
|
||||
.code
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* Buffer_Print -- Assembly text print to graphic buffer routine *
|
||||
;* *
|
||||
;* *
|
||||
;* *
|
||||
;* INPUT: *
|
||||
;* *
|
||||
;* OUTPUT: *
|
||||
;* *
|
||||
;* PROTO: *
|
||||
;* *
|
||||
;* WARNINGS: *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 01/17/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
Buffer_Print proc C public USES ebx ecx edx esi edi this_object:DWORD, string:DWORD, x_pixel:DWORD, y_pixel:DWORD, fcolor:DWORD, bcolor:DWORD
|
||||
|
||||
;PROC Buffer_Print C near
|
||||
;USES ebx,ecx,edx,esi,edi
|
||||
|
||||
;ARG this_object:DWORD
|
||||
;ARG string:DWORD
|
||||
;ARG x_pixel:DWORD
|
||||
;ARG y_pixel:DWORD
|
||||
;ARG fcolor:DWORD
|
||||
;ARG bcolor:DWORD
|
||||
|
||||
LOCAL infoblock:DWORD ; pointer to info block
|
||||
LOCAL offsetblock:DWORD ; pointer to offset block (UWORD *)
|
||||
LOCAL widthblock:DWORD ; pointer to width block (BYTE *)
|
||||
LOCAL heightblock:DWORD ; pointer to height block (UWORD *)
|
||||
|
||||
LOCAL curline:DWORD ; pointer to first column of current row.
|
||||
LOCAL bufferwidth:DWORD ; width of buffer (vpwidth + Xadd)
|
||||
LOCAL nextdraw:DWORD ; bufferwidth - width of cur character.
|
||||
LOCAL startdraw:DWORD ; where next character will start being drawn.
|
||||
|
||||
LOCAL char:DWORD ; current character value.
|
||||
|
||||
LOCAL maxheight:BYTE ; max height of characters in font.
|
||||
LOCAL bottomblank:BYTE ; amount of empty space below current character.
|
||||
LOCAL charheight:BYTE ; true height of current character.
|
||||
LOCAL vpwidth:DWORD
|
||||
LOCAL vpheight:DWORD
|
||||
LOCAL original_x:DWORD ; Starting X position.
|
||||
|
||||
|
||||
;-------------------------------- Where to draw -----------------------------------------------
|
||||
; Set up memory location to start drawing.
|
||||
mov ebx,[this_object] ; get a pointer to dest
|
||||
mov eax,[ebx].GraphicViewPort.GVPHeight ; get height of viewport
|
||||
mov [vpheight],eax ; save off height of viewport
|
||||
mov eax,[ebx].GraphicViewPort.GVPWidth ; get width of viewport
|
||||
mov [vpwidth],eax ; save it off for later
|
||||
add eax,[ebx].GraphicViewPort.GVPXAdd ; add in xadd for bytes_per_line
|
||||
add eax,[ebx].GraphicViewPort.GVPPitch ; add in pitch for direct daraw
|
||||
mov [bufferwidth],eax ; save it off for later use.
|
||||
|
||||
mul [y_pixel] ; multiply rowsize * y_pixel start.
|
||||
mov edi,[ebx].GraphicViewPort.GVPOffset ; get start of the viewport
|
||||
add edi,eax ; add y position to start of vp
|
||||
mov [curline],edi ; save 0,y address for line feed stuff.
|
||||
add edi,[x_pixel] ; add to get starting column in starting row.
|
||||
mov [startdraw],edi ; save it off.
|
||||
|
||||
mov eax,[x_pixel]
|
||||
mov [original_x],eax
|
||||
|
||||
;-------------------------------- Create block pointers ----------------------------------------
|
||||
; Get the pointer to the font.
|
||||
; We could check for NULL but why waste the time.
|
||||
; It is up to programmer to make sure it is set.
|
||||
mov esi,[FontPtr] ; Get the font pointer
|
||||
or esi,esi
|
||||
jz overflow
|
||||
|
||||
; Set up some pointers to the different memory blocks.
|
||||
; esi (FontPtr) is added to each to get the true address of each block.
|
||||
; Many registers are used for P5 optimizations.
|
||||
; ebx is used for InfoBlock which is then used in the next section.
|
||||
movzx eax,WORD PTR [esi+FONTOFFSETBLOCK] ; get offset to offset block
|
||||
movzx ebx,WORD PTR [esi+FONTINFOBLOCK] ; get offset to info block (must be ebx for height test)
|
||||
movzx ecx,WORD PTR [esi+FONTWIDTHBLOCK] ; get offset to width block
|
||||
movzx edx,WORD PTR [esi+FONTHEIGHTBLOCK] ; get offset to height block
|
||||
|
||||
add eax,esi ; add offset of FontPtr to offset block
|
||||
add ebx,esi ; add offset of FontPtr to info block
|
||||
add ecx,esi ; add offset of FontPtr to width block
|
||||
add edx,esi ; add offset of FontPtr to height block
|
||||
|
||||
mov [offsetblock],eax ; save offset to offset block
|
||||
mov [infoblock],ebx ; save offset to info block
|
||||
mov [widthblock],ecx ; save offset to width block
|
||||
mov [heightblock],edx ; save offset to height block
|
||||
|
||||
;------------------------------------------ Test for fit ----------------------------------------------
|
||||
; Test to make sure the height of the max character will fit on this line
|
||||
; and and not fall out of the viewport.
|
||||
; remember we set ebx to FONTINFOBLOCK above.
|
||||
movzx eax,BYTE PTR [ebx + FONTINFOMAXHEIGHT]; get the max height in font.
|
||||
mov [maxheight],al ; save it for later use.
|
||||
add eax,[y_pixel] ; add current y_value.
|
||||
cmp eax,[vpheight] ; are we over the edge?
|
||||
jg overflow ; if so, we're outa here.
|
||||
|
||||
mov [y_pixel],eax ; save for next line feed. y value for next line.
|
||||
|
||||
cld ; Make sure we are always forward copying.
|
||||
|
||||
;------------------------ Set palette foreground and background ----------------------------------
|
||||
mov eax,[fcolor] ; foreground color
|
||||
mov byte ptr [ColorXlat+1],al
|
||||
mov byte ptr [ColorXlat+16],al
|
||||
|
||||
mov eax,[bcolor] ; background color
|
||||
mov byte ptr [ColorXlat],al
|
||||
|
||||
;-------------------------------------------------------------------------------------------------
|
||||
;----------------------------------------- Main loop ----------------------------------------------
|
||||
; Now we go into the main loop of reading each character in the string and doing
|
||||
; something with it.
|
||||
next_char:
|
||||
; while (*string++)
|
||||
xor eax,eax ; zero out since we will just load al.
|
||||
mov esi,[string] ; get address on next character.
|
||||
lodsb ; load the character into al.
|
||||
test eax,0FFH ; test to see if character is a NULL
|
||||
jz done ; character is NULL, get outa here.
|
||||
|
||||
mov edi,[startdraw] ; Load the starting address.
|
||||
|
||||
mov [string],esi ; save index into string. (incremented by lodsb)
|
||||
|
||||
cmp al,10 ; is the character a line feed?
|
||||
je line_feed ; if so, go to special case.
|
||||
|
||||
cmp al,13 ; is the character a line feed?
|
||||
je line_feed ; if so, go to special case.
|
||||
|
||||
mov [char],eax ; save the character off for later reference.
|
||||
mov ebx,eax ; save it in ebx for later use also.
|
||||
|
||||
add eax,[widthblock] ; figure address of width of character.
|
||||
mov ecx,[x_pixel] ; get current x_pixel.
|
||||
movzx edx,BYTE PTR [eax] ; get the width of the character in dl.
|
||||
add ecx,edx ; add width of char to current x_pixel.
|
||||
mov eax,[FontXSpacing]
|
||||
add ecx,eax
|
||||
add [startdraw],edx ; save start draw for next character.
|
||||
add [startdraw],eax ; adjust for the font spacing value
|
||||
|
||||
cmp ecx,[vpwidth] ; is the pixel greater then the vp width?
|
||||
jg force_line_feed ; if so, force a line feed.
|
||||
|
||||
mov [x_pixel],ecx ; save value of start of next character.
|
||||
mov ecx,[bufferwidth] ; get amount to next y same x (one row down)
|
||||
sub ecx,edx ; take the current width off.
|
||||
mov [nextdraw],ecx ; save it to add to edi when done with a row.
|
||||
|
||||
; At this point we got the character. It is now time to find out specifics
|
||||
; about drawing the darn thing.
|
||||
; ebx = char so they can be used as an indexes.
|
||||
; edx = width of character for loop later.
|
||||
|
||||
; get offset of data for character into esi.
|
||||
shl ebx,1 ; mult by 2 to later use as a WORD index.
|
||||
mov esi,[offsetblock] ; get pointer to begining of offset block.
|
||||
add esi,ebx ; index into offset block.
|
||||
movzx esi,WORD PTR [esi] ; get true offset into data block from FontPtr.
|
||||
add esi,[FontPtr] ; Now add FontPtr address to get true address.
|
||||
|
||||
; Get top and bottom blank sizes and the true height of the character.
|
||||
add ebx,[heightblock] ; point ebx to element in height array.
|
||||
mov al,[ebx+1] ; load the data height into dl.
|
||||
mov cl,[ebx] ; load the first data row into cl.
|
||||
mov bl,[maxheight] ; get the max height of characters.
|
||||
mov [charheight],al ; get number of rows with data.
|
||||
add al,cl ; add the two heights.
|
||||
sub bl,al ; subract topblank + char height from maxheight.
|
||||
mov [bottomblank],bl ; save off the number of blank rows on the bottom.
|
||||
; leaving this section:
|
||||
; dl is still the width of the character.
|
||||
; cl is the height of the top blank area.
|
||||
|
||||
mov ebx,OFFSET ColorXlat ; setup ebx for xlat commands.
|
||||
mov dh,dl ; save the width of the character to restore each loop.
|
||||
|
||||
cmp cl,0 ; is there any blank rows on top?
|
||||
jz draw_char ; if not go and draw the real character.
|
||||
|
||||
xor eax,eax ; get color 0 for background.
|
||||
xlat ;[ebx] ; get translated color into al
|
||||
test al,al ; is it transparent black
|
||||
jnz loop_top ; if not go and write the color
|
||||
|
||||
;----------------------------------------- skip Top blank area ----------------------------------------
|
||||
; this case, the top is transparrent, but we need to increase our dest pointer to correct row.
|
||||
movzx eax,cl ; get number of rows into eax;
|
||||
mov ecx,edx ; save width since edx will be destroyed by mul.
|
||||
mul [bufferwidth] ; multiply that by the width of the buffer.
|
||||
mov edx,ecx ; restore the width
|
||||
add edi,eax ; update the pointer.
|
||||
jmp short draw_char ; now go draw the character.
|
||||
|
||||
;----------------------------------------- fill Top blank area ----------------------------------------
|
||||
; edi was set a long time ago.
|
||||
; al is the translated color
|
||||
loop_top:
|
||||
stosb ; store the value
|
||||
dec dh ; decrement our width.
|
||||
jnz loop_top ; if more width, continue on.
|
||||
|
||||
add edi,[nextdraw] ; add amount for entire row.
|
||||
|
||||
dec cl ; decrement or row count
|
||||
mov dh,dl ; restore width in dh for loop.
|
||||
jz draw_char ; we are done here, go draw the character.
|
||||
jmp short loop_top ; go back to top of loop.
|
||||
|
||||
|
||||
;----------------------------------------- Draw character ----------------------------------------------
|
||||
draw_char:
|
||||
movzx ecx,[charheight] ; get the height of character to count down rows.
|
||||
test ecx,ecx ; is there any data? (blank would not have any)
|
||||
jz next_char ; if no data, go on to next character.
|
||||
|
||||
while_data:
|
||||
lodsb ; get byte value from font data
|
||||
mov ah,al ; save hinibble
|
||||
and eax,0F00FH ; mask of low nibble in al hi nibble in ah.
|
||||
xlat ;[ebx] ; get new color
|
||||
|
||||
test al,al ; is it a transparent?
|
||||
jz short skiplo ; skip over write
|
||||
mov [edi],al ; write it out
|
||||
skiplo:
|
||||
inc edi
|
||||
dec dh ; decrement our width.
|
||||
jz short nextrow ; check if done with width of char
|
||||
|
||||
mov al,ah ; restore to get
|
||||
; test the time difference between looking up in a large table when shr al,4 is not done as
|
||||
; compared to using only a 16 byte table when using the shr al,4
|
||||
;shr al,4 ; shift the hi nibble down to low nibble
|
||||
xlat ;[ebx] ; get new color
|
||||
|
||||
test al,al ; is it a transparent?
|
||||
jz short skiphi ; skip over write
|
||||
mov [edi],al ; write it out
|
||||
skiphi:
|
||||
|
||||
inc edi
|
||||
dec dh ; decrement our width.
|
||||
jnz short while_data ; check if done with width of char
|
||||
|
||||
nextrow:
|
||||
add edi,[nextdraw] ; go to next line.
|
||||
dec ecx ; decrement the number of rows to go
|
||||
mov dh,dl ; restore our column count for row.
|
||||
jnz while_data ; more data for character.
|
||||
|
||||
; Now it is time to setup for clearing out the bottom of the character.
|
||||
movzx ecx,[bottomblank] ; get amount on bottom that is blank
|
||||
cmp ecx,0 ; if there is no blank bottom...
|
||||
jz next_char ; then skip to go to next character
|
||||
|
||||
xor eax,eax ; get color 0 for background.
|
||||
xlat ;[ebx] ; get translated color into al
|
||||
test al,al ; is it transparent black
|
||||
jz next_char ; skip the top black section to let the background through
|
||||
|
||||
mov dh,dl ; restore width in dh for loop.
|
||||
|
||||
;----------------------------------------- Blank below character -----------------------------------
|
||||
loop_bottom:
|
||||
stosb ; store the value
|
||||
dec dh ; decrement our width.
|
||||
jnz loop_bottom ; if more width, continue on.
|
||||
|
||||
add edi,[nextdraw] ; add amount for entire row.
|
||||
|
||||
mov dh,dl ; restore width in dh for loop.
|
||||
dec cl ; decrement or row count
|
||||
jz next_char ; we are done here, go to the next character.
|
||||
jmp short loop_bottom ; go back to top of loop.
|
||||
|
||||
;----------------------------------- end of next_char (main) loop ------------------------------------
|
||||
;-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
;----------------------------------- special case line feeds ----------------------------------------
|
||||
|
||||
force_line_feed:
|
||||
; decrement pointer *string so that it will be back at same character
|
||||
; when it goes through the loop.
|
||||
mov eax,[string] ; get string pointer.
|
||||
dec eax ; decrement it to point to previos char
|
||||
mov [string],eax ; save it back off.
|
||||
xor eax,eax
|
||||
; Now go into the line feed code.....
|
||||
|
||||
line_feed:
|
||||
mov bl,al
|
||||
mov edx,[y_pixel] ; get the current y pixel value.
|
||||
movzx ecx,[maxheight] ; get max height for later use.
|
||||
add ecx,[FontYSpacing]
|
||||
add edx,ecx ; add max height to y_pixel
|
||||
cmp edx,[vpheight] ; are we over the edge?
|
||||
jg overflow ; if so, we are outa here.
|
||||
|
||||
mov eax,[bufferwidth] ; get bytes to next line.
|
||||
mov edi,[curline] ; get start of current line.
|
||||
mul ecx ; mult max height * next line.
|
||||
|
||||
add edi,eax ; add adjustment to current line.
|
||||
add [y_pixel],ecx ; increment to our next y position.
|
||||
;;; DRD
|
||||
mov [curline],edi ; save it off for next line_feed.
|
||||
|
||||
; Move the cursor to either the left edge of the screen
|
||||
; or the left margin of the print position depending
|
||||
; on whether <CR> or <LF> was specified. <CR> = left margin
|
||||
; <LF> = left edge of screen
|
||||
xor eax,eax
|
||||
cmp bl,10
|
||||
je lfeed
|
||||
mov eax,[original_x]
|
||||
lfeed:
|
||||
mov [x_pixel],eax ; zero out x_pixel
|
||||
|
||||
add edi,eax
|
||||
;;; DRD mov [curline],edi ; save it off for next line_feed.
|
||||
mov [startdraw],edi ; save it off so we know where to draw next char.w
|
||||
|
||||
jmp next_char
|
||||
|
||||
overflow:
|
||||
mov [startdraw],0 ; Indicate that there is no valid next pos.
|
||||
done:
|
||||
mov eax,[startdraw] ; return this so calling routine
|
||||
ret ; can figure out where to draw next.
|
||||
|
||||
Buffer_Print endp
|
||||
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* GET_FONT_PALETTE_PTR -- Returns a pointer to the 256 byte font palette *
|
||||
;* *
|
||||
;* INPUT: none *
|
||||
;* *
|
||||
;* OUTPUT: none *
|
||||
;* *
|
||||
;* PROTO: void *Get_Font_Palette_Ptr(void); *
|
||||
;* *
|
||||
;* HISTORY: *
|
||||
;* 08/18/1995 PWG : Created. *
|
||||
;*=========================================================================*
|
||||
|
||||
Get_Font_Palette_Ptr proc C public
|
||||
|
||||
;GLOBAL C Get_Font_Palette_Ptr:NEAR
|
||||
|
||||
;PROC Get_Font_Palette_Ptr C near
|
||||
|
||||
mov eax, OFFSET ColorXlat
|
||||
ret
|
||||
|
||||
Get_Font_Palette_Ptr endp
|
||||
|
||||
|
||||
END
|
||||
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @author CCHyper
|
||||
* @author OmniBlade
|
||||
*
|
||||
* @brief Low level bitmap font string blitter.
|
||||
*
|
||||
* @copyright Chronoshift 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
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
* A full copy of the GNU General Public License can be found in
|
||||
* LICENSE
|
||||
*/
|
||||
#include "FUNCTION.H"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
using std::memcpy;
|
||||
using std::memset;
|
||||
|
||||
#define le16toh(x) x
|
||||
|
||||
#ifdef GAME_DLL
|
||||
extern char*& g_fontWidthBlockPtr;
|
||||
#else
|
||||
uint8_t g_ColorXlat[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
uint8_t byte_608988[] = {
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
15, 0, 0, 0 };
|
||||
|
||||
char* g_FontPtr = nullptr;
|
||||
char* g_fontWidthBlockPtr = nullptr;
|
||||
uint8_t g_FontHeight = 8;
|
||||
uint8_t g_FontWidth = 8;
|
||||
int g_FontXSpacing;
|
||||
int g_FontYSpacing;
|
||||
#endif
|
||||
|
||||
struct FontHeader
|
||||
{
|
||||
uint16_t file_size; // Size of the file
|
||||
uint8_t file_version; // file version? 0==EOB? 1==RA? 2==TS? what about RA2?
|
||||
uint8_t unknown; // 5==TD/RA 0==TS? unused in RA
|
||||
uint16_t start; // offset to start of font description Pad, always 0x0010
|
||||
uint16_t data_offset_list; // offset to bitmap data offset list, always 0x0014 as follows header
|
||||
uint16_t width_list; // points to list of widths
|
||||
uint16_t data; // points to graphics data, unused by RA code
|
||||
uint16_t line_list; // points to list of heights (or lines)
|
||||
uint16_t unknown_const; // Unknown entry (always 0x1012 or 0x1011) unused by RA
|
||||
uint8_t pad; // padding?
|
||||
uint8_t number_of_chars; // Number of chars in font - 1
|
||||
uint8_t max_height; // Max char height
|
||||
uint8_t max_width; // Max char width
|
||||
};
|
||||
|
||||
extern "C" void __cdecl Set_Font_Palette_Range(const void* colors, int first, int last)
|
||||
{
|
||||
byte* pal = (byte*)colors;
|
||||
first &= 15;
|
||||
last &= 15;
|
||||
|
||||
for (int i = first; i < last + 1; ++i) {
|
||||
g_ColorXlat[i] = *pal++;
|
||||
}
|
||||
}
|
||||
|
||||
void* __cdecl Set_Font(void const* fontptr)
|
||||
{
|
||||
FontHeader* header;
|
||||
|
||||
header = (FontHeader*)(fontptr);
|
||||
|
||||
if (fontptr) {
|
||||
g_FontPtr = (char*)(fontptr);
|
||||
g_fontWidthBlockPtr = (char*)(fontptr) + le16toh(header->width_list);
|
||||
g_FontHeight = le16toh(header->max_height);
|
||||
g_FontWidth = le16toh(header->max_width);
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
int __cdecl Char_Pixel_Width(char letter)
|
||||
{
|
||||
// Cast to unsigned as all blocks index from zero to NumberOfChars + 1
|
||||
// Original watcom compiler had char as an unsigned type by default.
|
||||
return g_fontWidthBlockPtr[(uint8_t)letter] + g_FontXSpacing;
|
||||
}
|
||||
|
||||
unsigned int __cdecl String_Pixel_Width(const char* string)
|
||||
{
|
||||
uint16_t width;
|
||||
uint16_t linewidth = 0;
|
||||
|
||||
if (string != nullptr) {
|
||||
width = 0;
|
||||
|
||||
while (*string != '\0') {
|
||||
if (*string == '\r') {
|
||||
++string;
|
||||
linewidth = max(linewidth, width);
|
||||
width = 0;
|
||||
}
|
||||
else {
|
||||
width += Char_Pixel_Width(*string++);
|
||||
}
|
||||
}
|
||||
|
||||
return max(linewidth, width);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl Buffer_Print2(GraphicViewPortClass& vp, const char* string, int x, int y, uint8_t fground, uint8_t bground)
|
||||
{
|
||||
FontHeader* fntheader = reinterpret_cast<FontHeader*>(g_FontPtr);
|
||||
int pitch = vp.Get_Full_Pitch();
|
||||
uint8_t* offset = y * pitch + (uint8_t*)(vp.Get_Offset());
|
||||
uint8_t* dst = x + offset;
|
||||
int char_width = 0;
|
||||
int base_x = x;
|
||||
|
||||
if (g_FontPtr != nullptr) {
|
||||
uint16_t* datalist =
|
||||
reinterpret_cast<uint16_t*>(reinterpret_cast<char*>(g_FontPtr) + le16toh(fntheader->data_offset_list));
|
||||
uint8_t* widthlist = reinterpret_cast<uint8_t*>(g_FontPtr) + le16toh(fntheader->width_list);
|
||||
uint16_t* linelist =
|
||||
reinterpret_cast<uint16_t*>(reinterpret_cast<char*>(g_FontPtr) + le16toh(fntheader->line_list));
|
||||
|
||||
int fntheight = fntheader->max_height;
|
||||
int ydisplace = g_FontYSpacing + fntheight;
|
||||
|
||||
// Check if we are drawing in bounds, we don't draw clipped text
|
||||
if (y + fntheight <= vp.Get_Height()) {
|
||||
int fntbottom = y + fntheight;
|
||||
// Set colors to draw with
|
||||
g_ColorXlat[1] = fground;
|
||||
g_ColorXlat[0] = bground;
|
||||
|
||||
while (true) {
|
||||
// Handle a new line
|
||||
uint8_t char_num;
|
||||
uint8_t* char_dst;
|
||||
while (true) {
|
||||
char_num = uint8_t(*string);
|
||||
|
||||
if (char_num == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char_dst = dst;
|
||||
++string;
|
||||
|
||||
if (char_num != '\n' && char_num != '\r') {
|
||||
break;
|
||||
}
|
||||
|
||||
// We don't handle clipping text, it either draws or it doesn't
|
||||
if (ydisplace + fntbottom > vp.Get_Height()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If its a new line, we are just going to set the start to an increased y displacement, hence x_pos
|
||||
// becomes 0
|
||||
x = char_num == '\n' ? 0 : base_x;
|
||||
dst = ydisplace * pitch + offset + x;
|
||||
offset += ydisplace * pitch;
|
||||
fntbottom += ydisplace;
|
||||
}
|
||||
|
||||
// Move to the start of the next char
|
||||
char_width = widthlist[char_num];
|
||||
dst += g_FontXSpacing + char_width;
|
||||
|
||||
// Handle text wrapping for long strings
|
||||
if (g_FontXSpacing + char_width + x > vp.Get_Width()) {
|
||||
--string;
|
||||
char_num = '\0';
|
||||
|
||||
// We don't handle clipping text, it either draws or it doesn't
|
||||
if (ydisplace + fntbottom > vp.Get_Height()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If its a new line, we are just going to set the start to an increased y displacement, hence x_pos
|
||||
// becomes 0
|
||||
x = char_num == '\n' ? 0 : base_x;
|
||||
dst = ydisplace * pitch + offset + x;
|
||||
offset += ydisplace * pitch;
|
||||
fntbottom += ydisplace;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Prepare variables for drawing
|
||||
x += g_FontXSpacing + char_width;
|
||||
int next_line = pitch - char_width;
|
||||
uint8_t* char_data = reinterpret_cast<uint8_t*>(g_FontPtr) + datalist[char_num];
|
||||
int char_lle = le16toh(linelist[char_num]);
|
||||
int char_ypos = char_lle & 0xFF;
|
||||
int char_lines = char_lle >> 8;
|
||||
int char_height = fntheight - (char_ypos + char_lines);
|
||||
int blit_width = widthlist[char_num];
|
||||
|
||||
// Fill unused lines if we have a color other than 0
|
||||
if (char_ypos) {
|
||||
uint8_t color = g_ColorXlat[0];
|
||||
if (color) {
|
||||
for (int i = char_ypos; i; --i) {
|
||||
memset(char_dst, color, blit_width);
|
||||
char_dst += pitch;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char_dst += pitch * char_ypos;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the character
|
||||
if (char_lines) {
|
||||
for (int i = 0; i < char_lines; ++i) {
|
||||
int width_todraw = blit_width;
|
||||
|
||||
while (width_todraw) {
|
||||
uint8_t color_packed;
|
||||
color_packed = *char_data++;
|
||||
uint8_t color = g_ColorXlat[color_packed & 0x0F];
|
||||
|
||||
if (color) {
|
||||
*char_dst = color;
|
||||
}
|
||||
|
||||
++char_dst;
|
||||
--width_todraw;
|
||||
|
||||
if (width_todraw == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
color = g_ColorXlat[color_packed >> 4];
|
||||
|
||||
if (color) {
|
||||
*char_dst = color;
|
||||
}
|
||||
|
||||
++char_dst;
|
||||
--width_todraw;
|
||||
}
|
||||
|
||||
char_dst += next_line;
|
||||
}
|
||||
|
||||
// Fill any remaining unused lines.
|
||||
if (char_height) {
|
||||
uint8_t color = g_ColorXlat[0];
|
||||
|
||||
if (color) {
|
||||
for (int i = char_height; i; --i) {
|
||||
memset(char_dst, color, blit_width);
|
||||
char_dst += pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" LONG __cdecl Buffer_Print(void* thisptr, const char* str, int x, int y, int fcolor, int bcolor)
|
||||
{
|
||||
Buffer_Print2(*(GraphicViewPortClass*)thisptr, str, x, y, fcolor, bcolor);
|
||||
return 0;
|
||||
}
|
||||
@@ -83,11 +83,6 @@ extern int CachedIconsDrawn;
|
||||
extern int UnCachedIconsDrawn;
|
||||
|
||||
|
||||
extern "C" void __cdecl Set_Font_Palette_Range(void const *palette, INT start_idx, INT end_idx)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
;***************************************************************************
|
||||
;* VVC::DRAW_LINE -- Scales a virtual viewport to another virtual viewport *
|
||||
|
||||
+28
-28
@@ -57,14 +57,14 @@
|
||||
* 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);
|
||||
}
|
||||
//int __cdecl Char_Pixel_Width(char chr)
|
||||
//{
|
||||
// int width;
|
||||
//
|
||||
// width = (unsigned char)*(FontWidthBlockPtr + (unsigned char)chr) + FontXSpacing;
|
||||
//
|
||||
// return(width);
|
||||
//}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@@ -84,26 +84,26 @@ int __cdecl Char_Pixel_Width(char chr)
|
||||
* 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);
|
||||
}
|
||||
//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);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
|
||||
|
||||
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
|
||||
/***************************************************************************
|
||||
** 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 : SET_FONT.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : September 6, 1991 *
|
||||
* *
|
||||
* Last Update : June 29, 1994 [SKB] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Set_Font -- Changes the default text printing font. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "font.h"
|
||||
#include <wwstd.h>
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* SET_FONT -- Changes the default text printing font. *
|
||||
* *
|
||||
* This routine will change the default text printing font for all *
|
||||
* text output. It handles updating the system where necessary. *
|
||||
* *
|
||||
* INPUT: fontptr -- Pointer to the font to change to. *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the previous font. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/06/1991 JLB : Created. *
|
||||
* 09/17/1991 JLB : Fixed return value bug. *
|
||||
* 01/31/1992 DRD : Modified to use new font format. *
|
||||
* 06/29/1994 SKB : modified for 32 bit library *
|
||||
*=========================================================================*/
|
||||
void * __cdecl Set_Font(void const *fontptr)
|
||||
{
|
||||
void *oldfont;
|
||||
char const *blockptr;
|
||||
|
||||
oldfont = (void *) FontPtr;
|
||||
|
||||
if (fontptr) {
|
||||
FontPtr = (void *) fontptr;
|
||||
|
||||
/*
|
||||
** Inform the system about the new font.
|
||||
*/
|
||||
|
||||
FontWidthBlockPtr = (char*)fontptr + *(unsigned short *)((char*)fontptr + FONTWIDTHBLOCK);
|
||||
blockptr = (char*)fontptr + *(unsigned short *)((char*)fontptr + FONTINFOBLOCK);
|
||||
FontHeight = *(blockptr + FONTINFOMAXHEIGHT);
|
||||
FontWidth = *(blockptr + FONTINFOMAXWIDTH);
|
||||
//Draw_Char_Setup();
|
||||
|
||||
#if FALSE
|
||||
WindowLines = WinH / FontHeight;
|
||||
WindowWidth = WinW << 3;
|
||||
WindowColumns = WindowWidth / FontWidth;
|
||||
#endif
|
||||
}
|
||||
|
||||
return(oldfont);
|
||||
}
|
||||
Reference in New Issue
Block a user