/* ** 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 . */ /*************************************************************************** ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** *************************************************************************** * * * Project Name : Library * * * * File Name : ICONSET.C * * * * Programmer : Joe L. Bostic * * * * Start Date : June 9, 1991 * * * * Last Update : September 15, 1993 [JLB] * * * *-------------------------------------------------------------------------* * Functions: * * Load_Icon_Set -- Loads an icons set and initializes it. * * Free_Icon_Set -- Frees allocations made by Load_Icon_Set(). * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ //#include "function.h" #include #include #include #include #include #include #include unsigned long Misc; void * cdecl Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize); void cdecl Free_Icon_Set(void const *iconset); long cdecl Get_Icon_Set_Size(void const *iconset); int cdecl Get_Icon_Set_Width(void const *iconset); int cdecl Get_Icon_Set_Height(void const *iconset); void * cdecl Get_Icon_Set_Icondata(void const *iconset); void * cdecl Get_Icon_Set_Trans(void const *iconset); void * cdecl Get_Icon_Set_Remapdata(void const *iconset); void * cdecl Get_Icon_Set_Palettedata(void const *iconset); int cdecl Get_Icon_Set_Count(void const *iconset); void * cdecl Get_Icon_Set_Map(void const *iconset); //#define ICON_PALETTE_BYTES 16 //#define ICON_MAX 256 /*************************************************************************** ** The terrain is rendered by using icons. These are the buffers that hold ** the icon data, remap tables, and remap index arrays. */ //PRIVATE char *IconPalette = NULL; // MCGA only. //PRIVATE char *IconRemap = NULL; // MCGA only. #define FORM_RPAL MAKE_ID('R','P','A','L') #define FORM_RTBL MAKE_ID('R','T','B','L') #define FORM_SSET MAKE_ID('S','S','E','T') #define FORM_SINF MAKE_ID('S','I','N','F') #define FORM_ICON MAKE_ID('I','C','O','N') #define FORM_TRNS MAKE_ID('T','R','N','S') #define FORM_MAP MAKE_ID('M','A','P',' ') /* ** This is the control structure at the start of a loaded icon set. It must match ** the structure in WWLIB.I! This structure MUST be a multiple of 16 bytes long. */ typedef struct { short Width; // Width of icons (pixels). short Height; // Height of icons (pixels). short Count; // Number of (logical) icons in this set. // BOOL Allocated; // Was this iconset allocated? short Allocated; // Was this iconset allocated? long Size; // Size of entire iconset memory block. long Icons; // Offset from buffer start to icon data. long Palettes; // Offset from buffer start to palette data. long Remaps; // Offset from buffer start to remap index data. long TransFlag; // Offset for transparency flag table. long ColorMap; long Map; // Icon map offset (if present). } IControl_Type; /*************************************************************************** * LOAD_ICON_SET -- Loads an icons set and initializes it. * * * * This routine will load an IFF icon set from disk. It handles all * * of the necessary allocations. * * * * INPUT: filename -- Name of the icon file. * * * * buffer -- Pointer to paragraph aligned buffer to hold data. * * * * size -- Size of the buffer (in bytes). * * * * OUTPUT: none * * * * WARNINGS: In EEGA mode the iconset buffer will be free because the * * icons will have been transferred to card ram. * * * * HISTORY: * * 06/21/1991 JLB : Created. * * 07/01/1991 JLB : Determines icon size from file. * * 07/15/1991 JLB : Load and uncompress onto the same buffer. * * 09/15/1993 JLB : Added EMS support. * *=========================================================================*/ void * cdecl Load_Icon_Set(char const *filename, void *iconsetptr, long buffsize) { int fh; // File handle of iconset. int bytespericon; // The number of bytes per icon. unsigned long icons=0; // Number of icons loaded. unsigned long size; // Size of the icon chunk (raw). unsigned long transsize; void *transptr=NULL; unsigned long mapsize; // Icon map chunk size. void *mapptr=NULL; // Icon map pointer. void *returnptr=NULL; // Iconset pointer returned by routine. BOOL allocated=FALSE; // Was the iconset block allocated? IControl_Type *idata=NULL; // Icon data loaded. long id; // ID of file openned. struct { char Width; // Width of icon in bytes. char Height; // Height of icon in bytes. char Format; // Graphic mode. //lint -esym(754,Format) char Bitplanes; // Number of bitplanes per icon. } sinf; /* ** Open the icon set for loading. If it is not a legal icon set ** data file, then abort. */ fh = Open_Iff_File(filename); if (fh != ERROR) { Read_File(fh, &id, sizeof(long)); if (id == FORM_ICON) { /* ** Determine the size of the icons and set up the graphic ** system accordingly. Also get the sizes of the various ** data blocks that have to be loaded. */ Read_Iff_Chunk(fh, FORM_SINF, &sinf, sizeof(sinf)); bytespericon = ((((int)sinf.Width)<<3)*(((int)sinf.Height)<<3)*(int)sinf.Bitplanes)>>3; size = Get_Iff_Chunk_Size(fh,FORM_SSET); transsize = Get_Iff_Chunk_Size(fh, FORM_TRNS); mapsize = Get_Iff_Chunk_Size(fh, FORM_MAP); /* ** Allocate the icon buffer if one isn't provided. First try EMS and ** then try conventional RAM. */ allocated = FALSE; if (!iconsetptr) { buffsize = size + transsize + mapsize + sizeof(IControl_Type); Misc = buffsize; iconsetptr = Alloc(buffsize, MEM_NORMAL); allocated = (iconsetptr != NULL); } if (iconsetptr && (size+transsize+mapsize+sizeof(IControl_Type)) <= buffsize) { idata = (IControl_Type *)iconsetptr; memset(idata, 0, sizeof(IControl_Type)); /* ** Initialize the iconset header structure. */ idata->Width = sinf.Width<<3; idata->Height = sinf.Height<<3; idata->Allocated = allocated; idata->Icons = sizeof(IControl_Type); idata->Map = idata->Icons + size; idata->TransFlag = idata->Map + mapsize; idata->Size = buffsize; { long val; val = Read_Iff_Chunk(fh, FORM_SSET, Add_Long_To_Pointer(iconsetptr, sizeof(IControl_Type)), size); icons = (int)(val/(long)bytespericon); idata = (IControl_Type *)iconsetptr; } if (mapsize) { icons = mapsize; } idata->Count = (short)icons; /* ** Limit buffer to only the size needed. This is done AFTER loading of the ** raw icon data because it might have been compressed and thus need any ** extra space to perform an overlapped decompression. */ if (buffsize > size + transsize + mapsize + sizeof(IControl_Type)) { buffsize = size + transsize + mapsize + sizeof(IControl_Type); } transptr = Add_Long_To_Pointer(iconsetptr, idata->TransFlag); Read_Iff_Chunk(fh, FORM_TRNS, transptr, transsize); idata = (IControl_Type *)iconsetptr; mapptr = Add_Long_To_Pointer(iconsetptr, idata->Map); Read_Iff_Chunk(fh, FORM_MAP, mapptr, mapsize); /* ** Let the graphic overlay know of the icon data. This could involve ** translation and other data manipulations. */ //Init_Stamps(iconsetptr); returnptr = iconsetptr; } } Close_Iff_File(fh); } return (returnptr); // Return with icon pointer. } /*************************************************************************** * FREE_ICON_SET -- Frees allocations made by Load_Icon_Set(). * * * * This routine is used to free up any allocations by Load_Icon_Set(). * * Use this routine when a new icon set is to be loaded. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 06/21/1991 JLB : Created. * *=========================================================================*/ void cdecl Free_Icon_Set(void const *iconset) { IControl_Type *icontrol; icontrol = (IControl_Type *)iconset; if (icontrol) { if (icontrol->Allocated) { Free((void *)iconset); } } } long cdecl Get_Icon_Set_Size(void const *iconset) { IControl_Type *icontrol; long size=0; icontrol = (IControl_Type *)iconset; if (icontrol) { size = icontrol->Size; } return(size); } int cdecl Get_Icon_Set_Width(void const *iconset) { IControl_Type *icontrol; int width=0; icontrol = (IControl_Type *)iconset; if (icontrol) { width = icontrol->Width; } return(width); } int cdecl Get_Icon_Set_Height(void const *iconset) { IControl_Type *icontrol; int height=0; icontrol = (IControl_Type *)iconset; if (icontrol) { height = icontrol->Height; } return(height); } void * cdecl Get_Icon_Set_Icondata(void const *iconset) { IControl_Type *icontrol; void *ptr=NULL; icontrol = (IControl_Type *)iconset; if (icontrol) { ptr = Add_Long_To_Pointer((void *)iconset, icontrol->Icons); } return(ptr); } void * cdecl Get_Icon_Set_Trans(void const *iconset) { IControl_Type *icontrol; void *ptr=NULL; icontrol = (IControl_Type *)iconset; if (icontrol) { ptr = Add_Long_To_Pointer((void *)iconset, icontrol->TransFlag); } return(ptr); } int cdecl Get_Icon_Set_Count(void const *iconset) { IControl_Type *icontrol; int count; icontrol = (IControl_Type *)iconset; if (icontrol) { count = icontrol->Count; } return(count); } void * cdecl Get_Icon_Set_Map(void const *iconset) { IControl_Type *icontrol; void *ptr=NULL; icontrol = (IControl_Type *)iconset; if (icontrol) { ptr = Add_Long_To_Pointer((void *)iconset, icontrol->Map); } return(ptr); }