summaryrefslogtreecommitdiff
path: root/src/tiledfile.c
blob: eaeb814b9df9b539620452b3dce4f57cf9b35120 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <raylib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "tiledfile.h"

const int i = 1;
#define is_bigendian() ( (*(char*)&i) == 0 )

void textureFromPixels(Texture2D *texOut, Color *pixels, int width, int height) {
    Image checkedIm = {
        .data = pixels,
        .width = width,
        .height = height,
        .format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
        .mipmaps = 1
    };

    *texOut = LoadTextureFromImage(checkedIm);
}

//! read rgba image from file
void readrgba(Texture2D *loc, int width, int height, FILE *file) {
    Color *pixels = malloc(width*height*4);
    fread(pixels, (size_t) width*height*4, (size_t) 1, file);
    textureFromPixels(loc, pixels, width, height);
}



//! write a big endian bytes from file
int writeb(char * in, size_t noBytes, FILE * file) {
    if (!is_bigendian()) {
        int tmp;
        // reverse byte order
        for(int i = 0; i < noBytes/2; i++) {
            tmp = in[i];
            in[i] = in[noBytes-i-1];
            in[noBytes-i-1] = tmp;
        }
        
    }

    return fwrite(in, (size_t)1, (size_t) noBytes, file);
}

//! read a big endian bytes from file
int readb(char * out, size_t noBytes, FILE * file) {
    if (!fread(out, (size_t)1, (size_t) noBytes, file))
        return 1;

    if (is_bigendian()) 
        return 0;

    int tmp;
    // reverse byte order
    for(int i = 0; i < noBytes/2; i++) {
        tmp = out[i];
        out[i] = out[noBytes-i-1];
        out[noBytes-i-1] = tmp;
    }

    return 0;
}

char getTiledMapTile(TiledMap tiledMap, int pos[2]) {
    return tiledMap.tilelayout[pos[1]*tiledMap.width + pos[0]];
}

void setTiledMapTile(TiledMap tiledMap, int pos[2], char tile) {
    tiledMap.tilelayout[pos[1]*tiledMap.width + pos[0]] = tile;
}

//! load tilemap data from file
TiledMap loadTiledMap(char * filename) {
    TiledMap tiledMap;
    FILE * file;

    if (!(file = fopen(filename, "rb"))) {
        fprintf(stderr, "Failed to load %s\n", filename);
        return tiledMap;
    }

    // skip header 
    fseek(file, 10, SEEK_CUR);
    // 4 bytes for int width
    readb((char *)&tiledMap.width, 4, file);
    // 4 bytes for int height
    readb((char *)&tiledMap.height, 4, file);

    size_t layoutSize = tiledMap.width*tiledMap.height;
    tiledMap.tilelayout = malloc(layoutSize);
    fread(tiledMap.tilelayout, layoutSize, 1, file);

    // read the pixel size of each tile
    readb((char *)&tiledMap.tileSize, 4, file);

    // read the atlas size
    readb((char *)&tiledMap.atlasSize[0], 4, file);
    readb((char *)&tiledMap.atlasSize[1], 4, file);

    // read the atlas itself
    size_t atlasSizeBytes = tiledMap.atlasSize[0]*tiledMap.tileSize*tiledMap.atlasSize[1]*tiledMap.tileSize*4;
    tiledMap.atlasData = malloc(atlasSizeBytes);
    fread(tiledMap.atlasData, atlasSizeBytes, (size_t) 1, file);

    tiledMap.tileCount = tiledMap.atlasSize[0]*tiledMap.atlasSize[1] + 1;

    fclose(file);
    return tiledMap;
}

TiledMap newTiledMap(Image atlas, int tileSize, int width, int height) {
    TiledMap tiledMap;
    tiledMap.width = width;
    tiledMap.height = height;
    tiledMap.tilelayout = malloc(width * height);

    tiledMap.tileSize = tileSize;

    tiledMap.atlasSize[0] = atlas.width / tileSize;
    tiledMap.atlasSize[1] = atlas.height / tileSize;

    tiledMap.atlasData = LoadImageColors(atlas);

    return tiledMap;
}

void saveTiledMap(char * filename, TiledMap tiledMap) {
    FILE * file;

    if (!(file = fopen(filename, "wb"))) {
        fprintf(stderr, "Failed to load %s\n", filename);
        return;
    }
    size_t layoutSize = tiledMap.width*tiledMap.height;
    size_t atlasSizeBytes = tiledMap.atlasSize[0]*tiledMap.tileSize*tiledMap.atlasSize[1]*tiledMap.tileSize*4;

    fwrite("TILEFILEv2", 10, 1, file);

    writeb((char *) &tiledMap.width, 4, file);
    writeb((char *) &tiledMap.height, 4, file);
    
    fwrite(tiledMap.tilelayout, 1, layoutSize, file);

    writeb((char *) &tiledMap.tileSize, 4, file);
    writeb((char *) &tiledMap.atlasSize[0], 4, file);
    writeb((char *) &tiledMap.atlasSize[1], 4, file);

    fwrite(tiledMap.atlasData, 1, atlasSizeBytes, file);

    fclose(file);
    fprintf(stderr, "Written tiledfiled to %s\n", filename);
}