472442aeb647e97e90cd28bb71ab800548a65036
[swan-dev] / tools / bmp2tiles / bmp2tiles.c
1 /**
2  * File              : bmp2tiles.c
3  * Author            : Robin Krens <robin@robinkrens.nl>
4  * Date              : 04.06.2022
5  * Last Modified Date: 12.06.2022
6  * Last Modified By  : Robin Krens <robin@robinkrens.nl>
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <stdbool.h>
13 #include <string.h>
14 #include <SDL2/SDL_image.h>
15
16 #define TILE_SZ         32
17 #define FOURBBP_ROW     8
18 #define FOURBPP_COL     8
19
20 typedef struct {
21         unsigned width;
22         unsigned height;
23         unsigned bpp;
24 } swan_gfx_t;
25
26 void set_info(swan_gfx_t * gfx, SDL_Surface * img)
27 {
28         gfx->width = img->w;
29         gfx->height = img->h;
30         gfx->bpp = img->format->BitsPerPixel;
31         
32         /* set userdata to iterate */
33         SDL_LockSurface(img);
34         img->userdata = img->pixels;
35         SDL_UnlockSurface(img);
36 }
37
38 void generate_4bpp_tile(unsigned char *buf, void * userdata, 
39                 bool packed)
40 {
41         unsigned char * ptr = (unsigned char *) userdata;
42         for (int i = 0; i < TILE_SZ; i+=4) {
43                 for (int j = 0; j < 4; ++j) {
44                         if (packed) { /* packed format */
45                                 buf[i+j] = ptr[0] << 4;
46                                 buf[i+j] |= ptr[1];
47                                 ptr += 2;
48                         } else { /* planar format */
49                                 for (int x = 0; x < 8; ++x) {
50                                         buf[i + j] = ptr[x] << j; 
51                                 }
52                         }
53                 }
54                 if (!packed)
55                         ptr += 8;
56         }
57 }
58
59 int main(void)
60 {
61         SDL_Surface * rawbmp;
62         FILE * ostream;
63         char filename[] = "test.bmp";
64         char outname[] = "test.gfx";
65         rawbmp = SDL_LoadBMP(filename);
66         
67         if (!rawbmp) {
68                 fprintf(stderr, "can not load .bmp file\n");
69                 exit(EXIT_FAILURE);
70         }
71
72         swan_gfx_t * gfx = malloc(sizeof(swan_gfx_t));
73         set_info(gfx, rawbmp);
74
75         unsigned char *tile_buf = malloc(sizeof(unsigned char) * TILE_SZ);
76         
77         if (gfx->bpp != 8) {
78                 fprintf(stderr, "warning: %d bpp format detected\n", rawbmp->format->BitsPerPixel);
79                 fprintf(stderr, "use --force in command to run\n");
80                 exit(EXIT_FAILURE);
81         }
82
83         ostream = fopen(outname, "w");
84         if (!ostream) {
85                 fprintf(stderr, "can not open file for writing!\n");
86                 exit(EXIT_FAILURE);
87         }
88
89         unsigned nr_tiles = 1;
90
91         for (int i = 0; i < nr_tiles; ++i) {
92                 generate_4bpp_tile(tile_buf, rawbmp->userdata, true);
93                 int ret = fwrite(tile_buf, sizeof(unsigned char), TILE_SZ, ostream);
94                 if (ret != TILE_SZ) {
95                         fprintf(stderr, "failed to convert, only write %d instead of %d\n", ret, TILE_SZ);
96                         goto cleanup;
97                 }
98         }
99
100 cleanup:
101         free(gfx);
102         SDL_FreeSurface(rawbmp);
103         fclose(ostream);
104 }