diff --git a/CMakeLists.txt b/CMakeLists.txt index 71e92e2..43cb3f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,6 @@ set(src_win32lib ./RedAlert/WIN32LIB/PROFILE.H ./RedAlert/WIN32LIB/PROFILE.INC ./RedAlert/WIN32LIB/RAWFILE.H - ./RedAlert/WIN32LIB/SET_FONT.CPP ./RedAlert/WIN32LIB/SHAPE.H ./RedAlert/WIN32LIB/SHAPE.INC ./RedAlert/WIN32LIB/SOS.H @@ -618,6 +617,7 @@ set(src_redalert ./RedAlert/_WSPROTO.CPP ./RedAlert/_WSPROTO.H ./REDALERT/MapScript.cpp + ./REDALERT/TXTPRNT.cpp ) set(src_external @@ -718,12 +718,6 @@ ADD_CUSTOM_COMMAND(OUTPUT TOBUFF.obj DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/WIN32LIB/TOBUFF.ASM COMMENT "generate TOBUFF.obj") -ADD_CUSTOM_COMMAND(OUTPUT TXTPRNT.obj - COMMAND ml -c - ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/TXTPRNT.ASM - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/TXTPRNT.ASM - COMMENT "generate TXTPRNT.obj") - ADD_CUSTOM_COMMAND(OUTPUT KEYFBUFF.obj COMMAND ml.exe /c /nolog /Zi /Zm /Cx ${CMAKE_CURRENT_SOURCE_DIR}/RedAlert/KEYFBUFF.ASM /Fl"" /Cp /W3 /errorReport:prompt @@ -738,7 +732,7 @@ ADD_CUSTOM_COMMAND(OUTPUT MMX.obj add_definitions(-DCHEAT_KEYS -DSCENARIO_EDITOR -DWINDOWS_IGNORE_PACKING_MISMATCH -DTRUE_FALSE_DEFINED -DWIN32 -DWINDOWS -DENGLISH -D_USRDLL -DREDALERT_EXPORTS) add_compile_options(/permissive+ /Zc:forScope- /Zp1) -add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external} TOBUFF.obj KEYFBUFF.obj TXTPRNT.obj MMX.obj) +add_executable(RedAlert ${src_win32lib} ${src_redalert} ${src_external} TOBUFF.obj KEYFBUFF.obj MMX.obj "REDALERT/TXTPRNT.CPP") diff --git a/REDALERT/TXTPRNT.ASM b/REDALERT/TXTPRNT.ASM deleted file mode 100644 index ae4fffc..0000000 --- a/REDALERT/TXTPRNT.ASM +++ /dev/null @@ -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 or was specified. = left margin - ; = 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 \ No newline at end of file diff --git a/REDALERT/TXTPRNT.CPP b/REDALERT/TXTPRNT.CPP new file mode 100644 index 0000000..e804732 --- /dev/null +++ b/REDALERT/TXTPRNT.CPP @@ -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 +#include + +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(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(reinterpret_cast(g_FontPtr) + le16toh(fntheader->data_offset_list)); + uint8_t* widthlist = reinterpret_cast(g_FontPtr) + le16toh(fntheader->width_list); + uint16_t* linelist = + reinterpret_cast(reinterpret_cast(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(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; +} diff --git a/REDALERT/WIN32LIB/DrawMisc.cpp b/REDALERT/WIN32LIB/DrawMisc.cpp index 5fad260..b2efa79 100644 --- a/REDALERT/WIN32LIB/DrawMisc.cpp +++ b/REDALERT/WIN32LIB/DrawMisc.cpp @@ -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 * diff --git a/REDALERT/WIN32LIB/FONT.CPP b/REDALERT/WIN32LIB/FONT.CPP index 8681a0e..04adc50 100644 --- a/REDALERT/WIN32LIB/FONT.CPP +++ b/REDALERT/WIN32LIB/FONT.CPP @@ -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); +//} diff --git a/REDALERT/WIN32LIB/SET_FONT.CPP b/REDALERT/WIN32LIB/SET_FONT.CPP deleted file mode 100644 index ed11342..0000000 --- a/REDALERT/WIN32LIB/SET_FONT.CPP +++ /dev/null @@ -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 - - - -/*************************************************************************** - * 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); -}