]> 4ch.mooo.com Git - 16.git/blob - 16/modex16/bitmap.c
16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / 16 / modex16 / bitmap.c
1 #include <stdio.h>\r
2 #include <stdlib.h>\r
3 #include "bitmap.h"\r
4 #include "modex16.h"\r
5 \r
6 static struct pcxHeader {\r
7     byte id;\r
8     byte version;\r
9     byte encoding;\r
10     byte bpp;\r
11     word xmin;\r
12     word ymin;\r
13     word xmax;\r
14     word ymax;\r
15     word hres;\r
16     word vres;\r
17     byte pal16[48];\r
18     byte res1;\r
19     word bpplane;\r
20     word palType;\r
21     word hScreenSize;\r
22     word vScreenSize;\r
23     byte padding[54];\r
24 } head;\r
25 \r
26 \r
27 static void loadPcxStage1(FILE *file, bitmap_t *result) {\r
28     long bufSize;\r
29     int index;\r
30     byte count, val;\r
31     long int pos;\r
32 \r
33     /* read the header */\r
34     fread(&head, sizeof(char), sizeof(struct pcxHeader), file);\r
35 \r
36     /* get the width and height */\r
37     result->width = head.xmax - head.xmin + 1;\r
38     result->height = head.ymax - head.ymin + 1;\r
39 \r
40     /* make sure this  is 8bpp */\r
41     if(head.bpp != 8) {\r
42         printf("I only know how to handle 8bpp pcx files!\n");\r
43         fclose(file);\r
44         exit(-2);\r
45     }\r
46 }\r
47 \r
48 \r
49 static void loadPcxPalette(FILE *file, bitmap_t *result) {\r
50     byte val;\r
51     int index;\r
52 \r
53     /* handle the palette */\r
54     fseek(file, -769, SEEK_END);\r
55     val = fgetc(file);\r
56     result->palette = modexNewPal();\r
57     if(head.version == 5 && val == 12) {\r
58         /* use the vga palette */\r
59         for(index=0; !feof(file) && index < PAL_SIZE; index++) {\r
60             val = fgetc(file);\r
61             result->palette[index] = val >> 2;\r
62         }\r
63     } else {\r
64         /* use the 16 color palette */\r
65         for(index=0; index<48; index++) {\r
66             result->palette[index]  = head.pal16[index];\r
67         }\r
68     }\r
69 }\r
70 \r
71 \r
72 bitmap_t\r
73 bitmapLoadPcx(char *filename) {\r
74     FILE *file;\r
75     bitmap_t result;\r
76     long bufSize;\r
77     int index;\r
78     byte count, val;\r
79 \r
80     /* open the PCX file for reading */\r
81     file = fopen(filename, "rb");\r
82     if(!file) {\r
83         printf("Could not open %s for reading.\n", filename);\r
84         exit(-2);\r
85     }\r
86 \r
87     /* load the first part of the pcx file */\r
88     loadPcxStage1(file, &result);\r
89 \r
90     /* allocate the buffer */\r
91     bufSize = result.width * result.height;\r
92     result.data = malloc(bufSize);\r
93     if(!result.data) {\r
94         printf("Could not allocate memory for bitmap data.");\r
95         fclose(file);\r
96         exit(-1);\r
97     }\r
98 \r
99     /*  read the buffer in */\r
100     index = 0;\r
101     do {\r
102         /* get the run length and the value */\r
103         count = fgetc(file);\r
104         if(0xC0 ==  (count & 0xC0)) { /* this is the run count */\r
105             count &= 0x3f;\r
106             val = fgetc(file);\r
107         } else {\r
108             val = count;\r
109             count = 1;\r
110         }\r
111 \r
112         /* write the pixel the specified number of times */\r
113         for(; count && index < bufSize; count--,index++)  {\r
114             result.data[index] = val;\r
115         }\r
116     } while(index < bufSize);\r
117 \r
118     loadPcxPalette(file, &result);\r
119 \r
120     fclose(file);\r
121 \r
122     return result;\r
123 }\r
124 \r
125 \r
126 tileset_t\r
127 bitmapLoadPcxTiles(char *filename, word twidth, word theight) {\r
128     tileset_t ts;\r
129     FILE *file;\r
130     bitmap_t result;\r
131     int i;\r
132 \r
133     /* open the PCX file for reading */\r
134     file = fopen(filename, "rb");\r
135     if(!file) {\r
136         printf("Could not open %s for reading.\n", filename);\r
137         exit(-2);\r
138     }\r
139 \r
140     /* load the first part of the pcx file */\r
141     loadPcxStage1(file, &result);\r
142 \r
143     /* get the number of tiles and set up the result structure */\r
144     ts.twidth = twidth;\r
145     ts.theight = theight;\r
146     ts.ntiles = (result.width/twidth) * (result.height/theight);\r
147     ts.palette = result.palette;\r
148 \r
149     /* allocate the pixel storage for the tiles */\r
150     ts.data = malloc(sizeof(byte*) * ts.ntiles);\r
151     ts.data[0] = malloc(sizeof(byte) * ts.ntiles * twidth * theight);\r
152     for(i=1; i < ts.ntiles; i++) {\r
153         ts.data[i] = ts.data[i-1] + twidth * theight;\r
154     }\r
155     \r
156     /* finish off the file */\r
157     loadPcxPalette(file, &result);\r
158 \r
159     fclose(file);\r
160 \r
161     return ts;\r
162 }\r