OSDN Git Service

p16 is being worked on a bunch by me wwww [16_ca needs huge amounts of work and I...
[proj16/16.git] / 16 / src / lib / bitmap.c
1 /* Project 16 Source Code~\r
2  * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
3  *\r
4  * This file is part of Project 16.\r
5  *\r
6  * Project 16 is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * Project 16 is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or\r
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
19  * Fifth Floor, Boston, MA 02110-1301 USA.\r
20  *\r
21  */\r
22 \r
23 #include <stdio.h>\r
24 #include <stdlib.h>\r
25 #include <malloc.h>\r
26 #include "16/src/lib/bitmap.h"\r
27 #include "src/lib/16_mm.h"\r
28 #include "src/lib/16_pm.h"\r
29 #include "src/lib/16_ca.h"\r
30 \r
31 static struct pcxHeader {\r
32         byte id;\r
33         byte version;\r
34         byte encoding;\r
35         byte bpp;\r
36         word xmin;\r
37         word ymin;\r
38         word xmax;\r
39         word ymax;\r
40         word hres;\r
41         word vres;\r
42         byte pal16[48];\r
43         byte res1;\r
44         word bpplane;\r
45         word palType;\r
46         word hScreenSize;\r
47         word vScreenSize;\r
48         byte padding[54];\r
49 } head;\r
50 \r
51 static void loadPcxStage1(FILE *file, bitmap_t *result) {\r
52         //long bufSize;\r
53         //int index;\r
54         //byte count, val;\r
55         //long int pos;\r
56 \r
57         /* read the header */\r
58         fread(&head, sizeof(char), sizeof(struct pcxHeader), file);\r
59 \r
60         /* get the width and height */\r
61         result->width = head.xmax - head.xmin + 1;\r
62         result->height = head.ymax - head.ymin + 1;\r
63 \r
64         /* make sure this  is 8bpp */\r
65         if(head.bpp != 8) {\r
66                 printf("I only know how to handle 8bpp pcx files!\n");\r
67                 fclose(file);\r
68                 exit(-2);\r
69         }\r
70 }\r
71 \r
72 \r
73 static void loadPcxPalette(FILE *file, bitmap_t *result) {\r
74         byte val;\r
75         int index;\r
76 \r
77         /* handle the palette */\r
78         fseek(file, -769, SEEK_END);\r
79         val = fgetc(file);\r
80         result->palette = modexNewPal();\r
81         if(head.version == 5 && val == 12) {\r
82         /* use the vga palette */\r
83         for(index=0; !feof(file) && index < PAL_SIZE; index++) {\r
84                 val = fgetc(file);\r
85                 result->palette[index] = val >> 2;\r
86         }\r
87         } else {\r
88         /* use the 16 color palette */\r
89         for(index=0; index<48; index++) {\r
90                 result->palette[index]  = head.pal16[index];\r
91         }\r
92         }\r
93 }\r
94 \r
95 \r
96 bitmap_t\r
97 bitmapLoadPcx(char *filename, global_game_variables_t *gv) {\r
98         FILE *file;\r
99         bitmap_t result;\r
100         dword bufSize;\r
101         int index;\r
102         byte count, val;\r
103 \r
104         /* open the PCX file for reading */\r
105         file = fopen(filename, "rb");\r
106         if(!file) {\r
107                 printf("Could not open %s for reading.\n", filename);\r
108                 //exit(-2);\r
109         }\r
110 \r
111         /* load the first part of the pcx file */\r
112         loadPcxStage1(file, &result);\r
113 \r
114         /* allocate the buffer */\r
115         //printf("%zu\n", _memmax());\r
116         bufSize = (/*(dword)*/result.width * result.height);\r
117         //CA_LoadFile(filename, (memptr *)(result.data), gv);\r
118         result.data = malloc(bufSize);\r
119 \r
120 //      result.data = (byte far *)_fmalloc(bufSize);\r
121 //      result.data = (byte __huge *)halloc(bufSize, sizeof(byte));\r
122         /*printf("&bufSize=%p\n", &bufSize);\r
123         printf("&result.data=%p\n", result.data);\r
124         printf("Size of block is %zu bytes\n", _msize(result.data));\r
125         printf("Size of bufSize is %zu bytes\n", bufSize);\r
126         printf("Size of result.width is %zu \n", result.width);\r
127         printf("Size of result.height is %zu \n", result.height);\r
128         printf("Dimensions of result is %lu\n", (dword)result.width*result.height);*/\r
129         if(!result.data) {\r
130                 fprintf(stderr, "Could not allocate memory for bitmap data.");\r
131                 fclose(file);\r
132                 //exit(-1);\r
133         }\r
134 \r
135         /*  read the buffer in */\r
136         index = 0;\r
137         do {\r
138         /* get the run length and the value */\r
139         count = fgetc(file);\r
140         if(0xC0 ==  (count & 0xC0)) { /* this is the run count */\r
141                 count &= 0x3f;\r
142                 val = fgetc(file);\r
143         } else {\r
144                 val = count;\r
145                 count = 1;\r
146         }\r
147 \r
148         /* write the pixel the specified number of times */\r
149         for(; count && index < bufSize; count--,index++)  {\r
150                 result.data[index] = val;\r
151         }\r
152         } while(index < bufSize);\r
153         //printf("index=%d\n", index);\r
154 \r
155         loadPcxPalette(file, &result);\r
156 \r
157         fclose(file);\r
158 \r
159         return result;\r
160 }\r
161 \r
162 //TODO: update!!\r
163 tileset_t\r
164 bitmapLoadPcxTiles(char *filename, word twidth, word theight) {\r
165         tileset_t ts;\r
166         FILE *file;\r
167         bitmap_t result;\r
168         int i;\r
169 \r
170         /* open the PCX file for reading */\r
171         file = fopen(filename, "rb");\r
172         if(!file) {\r
173                 printf("Could not open %s for reading.\n", filename);\r
174                 exit(-2);\r
175         }\r
176 \r
177         /* load the first part of the pcx file */\r
178         loadPcxStage1(file, &result);\r
179 \r
180         /* get the number of tiles and set up the result structure */\r
181         ts.twidth = twidth;\r
182         ts.theight = theight;\r
183         ts.ntiles = (result.width/twidth) * (result.height/theight);\r
184         ts.palette = result.palette;\r
185 \r
186         /* allocate the pixel storage for the tiles */\r
187         ts.data = _fmalloc(sizeof(byte*) * ts.ntiles);\r
188         //ts.data[0] = malloc(sizeof(byte) * ts.ntiles * twidth * theight);\r
189         for(i=1; i < ts.ntiles; i++) {\r
190                 ts.data[i] = ts.data[i-1] + twidth * theight;\r
191         }\r
192 \r
193         /* finish off the file */\r
194         loadPcxPalette(file, &result);\r
195 \r
196         fclose(file);\r
197 \r
198         return ts;\r
199 }\r
200 \r
201 byte *\r
202 modexNewPal() {\r
203         byte *ptr;\r
204         ptr = malloc(PAL_SIZE);\r
205 \r
206         // handle errors\r
207         if(!ptr) {\r
208                 printf("Could not allocate palette.\n");\r
209         }\r
210 \r
211         return ptr;\r
212 }\r