1 //RETRO HACK TO REDO
2 //SDL SAVEBMP (used in screenSnapShot.c)
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <errno.h>
7 
8 #include "main.h"
9 #include "screen.h"
10 
11 extern unsigned char savbkg[1024*1024*2];
12 
13 typedef struct                       /**** BMP file header structure ****/
14 {
15    unsigned short bfType;           /* Magic number for file */
16    unsigned int   bfSize;           /* Size of file */
17    unsigned short bfReserved1;      /* Reserved */
18    unsigned short bfReserved2;      /* ... */
19    unsigned int   bfOffBits;        /* Offset to bitmap data */
20 } BITMAPFILEHEADER;
21 
22 #  define BF_TYPE 0x4D42             /* "MB" */
23 
24 typedef struct                       /**** BMP file info structure ****/
25 {
26    unsigned int   biSize;           /* Size of info header */
27    int            biWidth;          /* Width of image */
28    int            biHeight;         /* Height of image */
29    unsigned short biPlanes;         /* Number of color planes */
30    unsigned short biBitCount;       /* Number of bits per pixel */
31    unsigned int   biCompression;    /* Type of compression to use */
32    unsigned int   biSizeImage;      /* Size of image data */
33    int            biXPelsPerMeter;  /* X pixels per meter */
34    int            biYPelsPerMeter;  /* Y pixels per meter */
35    unsigned int   biClrUsed;        /* Number of colors used */
36    unsigned int   biClrImportant;   /* Number of important colors */
37 } BITMAPINFOHEADER;
38 
39 /*
40  * Constants for the biCompression field...
41  */
42 
43 #  define BI_RGB       0             /* No compression - straight BGR data */
44 #  define BI_RLE8      1             /* 8-bit run-length compression */
45 #  define BI_RLE4      2             /* 4-bit run-length compression */
46 #  define BI_BITFIELDS 3             /* RGB bitmap with RGB masks */
47 
48 typedef struct                       /**** Colormap entry structure ****/
49 {
50    unsigned char  rgbBlue;          /* Blue value */
51    unsigned char  rgbGreen;         /* Green value */
52    unsigned char  rgbRed;           /* Red value */
53    unsigned char  rgbReserved;      /* Reserved */
54 } RGBQUAD;
55 
56 typedef struct                       /**** Bitmap information structure ****/
57 {
58    BITMAPINFOHEADER bmiHeader;      /* Image header */
59    RGBQUAD          bmiColors[256]; /* Image colormap */
60 } BITMAPINFO;
61 
62 /*
63  * 'read_word()' - Read a 16-bit unsigned integer.
64  */
65 
66    static unsigned short     /* O - 16-bit unsigned integer */
read_word(FILE * fp)67 read_word(FILE *fp)       /* I - File to read from */
68 {
69    unsigned char b0, b1; /* Bytes from file */
70 
71    b0 = getc(fp);
72    b1 = getc(fp);
73 
74    return ((b1 << 8) | b0);
75 }
76 
77 /*
78  * 'read_dword()' - Read a 32-bit unsigned integer.
79  */
80 
81    static unsigned int               /* O - 32-bit unsigned integer */
read_dword(FILE * fp)82 read_dword(FILE *fp)              /* I - File to read from */
83 {
84    unsigned char b0, b1, b2, b3; /* Bytes from file */
85 
86    b0 = getc(fp);
87    b1 = getc(fp);
88    b2 = getc(fp);
89    b3 = getc(fp);
90 
91    return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
92 }
93 
94 
95 /*
96  * 'read_long()' - Read a 32-bit signed integer.
97  */
98 
99    static int                        /* O - 32-bit signed integer */
read_long(FILE * fp)100 read_long(FILE *fp)               /* I - File to read from */
101 {
102    unsigned char b0, b1, b2, b3; /* Bytes from file */
103 
104    b0 = getc(fp);
105    b1 = getc(fp);
106    b2 = getc(fp);
107    b3 = getc(fp);
108 
109    return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
110 }
111 
112 
113 /*
114  * 'write_word()' - Write a 16-bit unsigned integer.
115  */
116 
117    static int                     /* O - 0 on success, -1 on error */
write_word(FILE * fp,unsigned short w)118 write_word(FILE           *fp, /* I - File to write to */
119       unsigned short w)   /* I - Integer to write */
120 {
121    putc(w, fp);
122    return (putc(w >> 8, fp));
123 }
124 
125 
126 /*
127  * 'write_dword()' - Write a 32-bit unsigned integer.
128  */
129 
130    static int                    /* O - 0 on success, -1 on error */
write_dword(FILE * fp,unsigned int dw)131 write_dword(FILE         *fp, /* I - File to write to */
132       unsigned int dw)  /* I - Integer to write */
133 {
134    putc(dw, fp);
135    putc(dw >> 8, fp);
136    putc(dw >> 16, fp);
137    return (putc(dw >> 24, fp));
138 }
139 
140 
141 /*
142  * 'write_long()' - Write a 32-bit signed integer.
143  */
144 
145    static int           /* O - 0 on success, -1 on error */
write_long(FILE * fp,int l)146 write_long(FILE *fp, /* I - File to write to */
147       int  l)   /* I - Integer to write */
148 {
149    putc(l, fp);
150    putc(l >> 8, fp);
151    putc(l >> 16, fp);
152    return (putc(l >> 24, fp));
153 }
154 
155 
156 
SDL_SaveBMP(SDL_Surface * surface,const char * file)157 int SDL_SaveBMP(SDL_Surface *surface,const char *file){
158 
159    FILE *fp;                      /* Open file pointer */
160    int  i,size,                     /* Size of file */
161         infosize,                 /* Size of bitmap info */
162         bitsize;                  /* Size of bitmap pixels */
163 
164    unsigned char *pixels,*pixflip;
165    unsigned short int temp;
166 
167 
168    /* Try opening the file; use "wb" mode to write this *binary* file. */
169    if ((fp = fopen(file, "wb")) == NULL){
170       printf("openfile faided %s\n",file);
171       return (-1);
172    }
173 
174    pixels = malloc(sizeof(unsigned char)*3*retrow*retroh);
175 
176    bitsize = 3*retrow*retroh;
177 
178    /* Figure out the header size */
179    infosize = sizeof(BITMAPINFOHEADER);
180 
181    size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;
182 
183    /* Write the file header, bitmap information, and bitmap pixel data... */
184 
185    write_word(fp, BF_TYPE);        /* bfType */
186    write_dword(fp, size);          /* bfSize */
187    write_word(fp, 0);              /* bfReserved1 */
188    write_word(fp, 0);              /* bfReserved2 */
189    write_dword(fp, 18 + infosize); /* bfOffBits */
190 
191    write_dword(fp, 40/*info->bmiHeader.biSize*/);
192    write_long(fp, retrow/*info->bmiHeader.biWidth*/);
193    write_long(fp, retroh/*info->bmiHeader.biHeight*/);
194    write_word(fp,   1/* info->bmiHeader.biPlanes*/);
195    write_word(fp,  24/*info->bmiHeader.biBitCount*/);
196    write_dword(fp,  0/*info->bmiHeader.biCompression*/);
197    write_dword(fp,  3*retrow*retroh/*info->bmiHeader.biSizeImage*/);
198    write_long(fp,   0/*info->bmiHeader.biXPelsPerMeter*/);
199    write_long(fp,   0/*info->bmiHeader.biYPelsPerMeter*/);
200    write_dword(fp,  0/*info->bmiHeader.biClrUsed*/);
201    write_dword(fp,  0/*info->bmiHeader.biClrImportant*/);
202 
203 
204    // RGB565 to bgr
205 
206    unsigned short int *ptr=(unsigned short int*)&savbkg[0];
207 
208    short R8, G8 , B8 ;
209 
210    for (i = 0; i < retrow * retroh; i++)
211    {
212       temp = (unsigned short  int) (*ptr)&0xffff;
213 
214 #define R5 ((temp>>11)&0x1F)
215 #define G6 ((temp>>5 )&0x3F)
216 #define B5 ((temp    )&0x1F)
217 
218       R8 = ( R5 * 527 + 23 ) >> 6;
219       G8 = ( G6 * 259 + 33 ) >> 6;
220       B8 = ( B5 * 527 + 23 ) >> 6;
221 
222       ptr++;
223 
224       //rbg?
225       pixels[(i*3)+0]= R8;
226       pixels[(i*3)+1]= B8;
227       pixels[(i*3)+2]= G8;
228    }
229 
230    const int bw = retrow*3;
231    int pad;
232 
233    // Write the bitmap image upside down
234    pixflip = (Uint8 *) pixels + (retroh *bw);
235    pad = ((bw % 4) ? (4 - (bw % 4)) : 0);
236    while (pixflip > (Uint8 *) pixels)
237    {
238       pixflip -= bw;
239       if (fwrite(pixflip, 1, bw, fp) != bw)
240       {
241          printf("write erreur %d\n",bw);
242          free(pixels);
243          fclose(fp);
244          return -1;
245       }
246       if (pad)
247       {
248          const Uint8 padbyte = 0;
249          for (i = 0; i < pad; ++i)
250             fwrite( &padbyte, 1, 1, fp);
251       }
252    }
253 
254    fclose(fp);
255    free(pixels);
256 
257    return (0);
258 
259 }
260 
261