diff options
author | Mike Buland <mike@xagasoft.com> | 2015-04-08 08:40:05 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2015-04-08 08:40:05 -0600 |
commit | f314041b6b37bb9274d9fc79946858341befa0f2 (patch) | |
tree | 3ad385b2bdedeb367ae8b26341d7044c340dc153 | |
parent | 518619603ab3c49b7fdfcf19c439c1a30668164f (diff) | |
download | lost-f314041b6b37bb9274d9fc79946858341befa0f2.tar.gz lost-f314041b6b37bb9274d9fc79946858341befa0f2.tar.bz2 lost-f314041b6b37bb9274d9fc79946858341befa0f2.tar.xz lost-f314041b6b37bb9274d9fc79946858341befa0f2.zip |
Added image goo + font support.
-rw-r--r-- | build.sh | 2 | ||||
-rw-r--r-- | src/font.cpp | 192 | ||||
-rw-r--r-- | src/font.h | 65 | ||||
-rw-r--r-- | src/image.cpp | 143 | ||||
-rw-r--r-- | src/image.h | 27 | ||||
-rw-r--r-- | src/main.cpp | 16 | ||||
-rw-r--r-- | src/palette.cpp | 32 | ||||
-rw-r--r-- | src/palette.h | 22 | ||||
-rw-r--r-- | src/renderpng.cpp | 251 |
9 files changed, 658 insertions, 92 deletions
@@ -1,3 +1,3 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | 2 | ||
3 | exec g++ src/*.cpp -o lost.exe -L/usr/lib -lpng16 -I/usr/include -lz | 3 | exec g++ -ggdb src/*.cpp -o lost.exe -L/usr/lib -lpng16 -I/usr/include -lz -ggdb |
diff --git a/src/font.cpp b/src/font.cpp new file mode 100644 index 0000000..27204a7 --- /dev/null +++ b/src/font.cpp | |||
@@ -0,0 +1,192 @@ | |||
1 | #include "font.h" | ||
2 | |||
3 | #include <stdio.h> | ||
4 | #include <string.h> | ||
5 | |||
6 | #include <exception> | ||
7 | |||
8 | #define fh (( (FILE *)rawfh )) | ||
9 | |||
10 | Font::Font( const char *sSrcFile ) : | ||
11 | iTableTop( 0 ), | ||
12 | pTable( NULL ) | ||
13 | { | ||
14 | iTableTop = 128; | ||
15 | pTable = new Glyph*[iTableTop]; | ||
16 | memset( pTable, 0, sizeof(Glyph*)*iTableTop ); | ||
17 | Parser p( sSrcFile, *this ); | ||
18 | p.parse(); | ||
19 | } | ||
20 | |||
21 | Font::~Font() | ||
22 | { | ||
23 | } | ||
24 | |||
25 | Font::Parser::Parser( const char *sSrcFile, Font &rFont ) : | ||
26 | rFont( rFont ), | ||
27 | rawfh( NULL ), | ||
28 | sLine( NULL ), | ||
29 | bDone( false ) | ||
30 | { | ||
31 | sLine = new char[1024]; | ||
32 | rawfh = fopen( sSrcFile, "rt" ); | ||
33 | } | ||
34 | |||
35 | Font::Parser::~Parser() | ||
36 | { | ||
37 | delete[] sLine; | ||
38 | fclose( fh ); | ||
39 | } | ||
40 | |||
41 | void Font::Parser::parse() | ||
42 | { | ||
43 | header(); | ||
44 | characters(); | ||
45 | if( strncasecmp("ENDFONT", sLine, 7 ) ) | ||
46 | { | ||
47 | printf("End of file reached, but no end marker.\n"); | ||
48 | throw std::exception(); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | void Font::Parser::getLine() | ||
53 | { | ||
54 | for(;;) | ||
55 | { | ||
56 | if( fgets( sLine, 1024, fh ) == NULL ) | ||
57 | { | ||
58 | sLine[0] = '\0'; | ||
59 | bDone = true; | ||
60 | printf("Premature end of file.\n"); | ||
61 | throw std::exception(); | ||
62 | return; | ||
63 | } | ||
64 | |||
65 | if( strncasecmp("COMMENT ", sLine, 8 ) ) | ||
66 | { | ||
67 | return; | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | void Font::Parser::header() | ||
73 | { | ||
74 | getLine(); | ||
75 | if( strncasecmp("STARTFONT 2.1", sLine, 13 ) ) | ||
76 | { | ||
77 | printf("Bad format: %s\n", sLine); | ||
78 | throw std::exception(); | ||
79 | } | ||
80 | |||
81 | for(;;) | ||
82 | { | ||
83 | getLine(); | ||
84 | if( strncasecmp("SIZE ", sLine, 5 ) == 0 ) | ||
85 | { | ||
86 | } | ||
87 | else if( strncasecmp("FONTBOUNDINGBOX ", sLine, 16 ) == 0 ) | ||
88 | { | ||
89 | } | ||
90 | else if( strncasecmp("STARTPROPERTIES ", sLine, 16 ) == 0 ) | ||
91 | { | ||
92 | properties(); | ||
93 | } | ||
94 | else if( strncasecmp("CHARS ", sLine, 6 ) == 0 ) | ||
95 | { | ||
96 | return; | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | void Font::Parser::properties() | ||
102 | { | ||
103 | for(;;) | ||
104 | { | ||
105 | getLine(); | ||
106 | if( strncasecmp("ENDPROPERTIES", sLine, 13 ) == 0 ) | ||
107 | return; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | void Font::Parser::characters() | ||
112 | { | ||
113 | for(;;) | ||
114 | { | ||
115 | getLine(); | ||
116 | if( strncasecmp("STARTCHAR ", sLine, 10 ) == 0 ) | ||
117 | character(); | ||
118 | else | ||
119 | return; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | uint8_t hex2byte( const char *str ) | ||
124 | { | ||
125 | uint8_t ret = 0; | ||
126 | |||
127 | ret |= ((*str >= '0' && *str <= '9')?(*str-'0'):( | ||
128 | (*str >= 'a' && *str <= 'f')?(*str-'a'+10):( | ||
129 | (*str >= 'A' && *str <= 'F')?(*str-'A'+10):0 | ||
130 | )))<<4; | ||
131 | str++; | ||
132 | ret |= (*str >= '0' && *str <= '9')?(*str-'0'):( | ||
133 | (*str >= 'a' && *str <= 'f')?(*str-'a'+10):( | ||
134 | (*str >= 'A' && *str <= 'F')?(*str-'A'+10):0 | ||
135 | )); | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | void Font::Parser::character() | ||
140 | { | ||
141 | char sName[1024]; | ||
142 | int32_t iIdx = -1; | ||
143 | strcpy( sName, sLine+10 ); | ||
144 | Glyph *pChar = new Glyph(); | ||
145 | |||
146 | for(;;) | ||
147 | { | ||
148 | getLine(); | ||
149 | if( strncasecmp("ENCODING ", sLine, 9 ) == 0 ) | ||
150 | { | ||
151 | sscanf( sLine+9, "%d", &iIdx ); | ||
152 | } | ||
153 | else if( strncasecmp("DWIDTH ", sLine, 7 ) == 0 ) | ||
154 | { | ||
155 | sscanf( sLine+7, "%d %d", &pChar->pDevOff.x, &pChar->pDevOff.y ); | ||
156 | } | ||
157 | else if( strncasecmp("BBX ", sLine, 4 ) == 0 ) | ||
158 | { | ||
159 | sscanf( sLine+4, "%d %d %d %d", | ||
160 | &pChar->pBox.x, &pChar->pBox.y, | ||
161 | &pChar->pOff.x, &pChar->pOff.y | ||
162 | ); | ||
163 | } | ||
164 | else if( strncasecmp("BITMAP", sLine, 6 ) == 0 ) | ||
165 | { | ||
166 | pChar->iRowBytes = pChar->pBox.x/8 + ((pChar->pBox.x%8)==0?0:1); | ||
167 | |||
168 | pChar->pData = new uint8_t[pChar->iRowBytes*pChar->pBox.y]; | ||
169 | // Read bitmap | ||
170 | for( int y = 0; y < pChar->pBox.y; y++ ) | ||
171 | { | ||
172 | getLine(); | ||
173 | for( int x = 0; x < pChar->iRowBytes; x++ ) | ||
174 | { | ||
175 | pChar->pData[x+y*pChar->iRowBytes] = hex2byte( sLine+(2*x) ); | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | else if( strncasecmp("ENDCHAR", sLine, 7 ) == 0 ) | ||
180 | { | ||
181 | if( iIdx >= 0 && iIdx < rFont.iTableTop ) | ||
182 | { | ||
183 | rFont.pTable[iIdx] = pChar; | ||
184 | //printf("Char %d: %s\n", iIdx, sName ); | ||
185 | } | ||
186 | else | ||
187 | delete pChar; | ||
188 | return; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
diff --git a/src/font.h b/src/font.h new file mode 100644 index 0000000..802de9d --- /dev/null +++ b/src/font.h | |||
@@ -0,0 +1,65 @@ | |||
1 | #ifndef FONT_H | ||
2 | #define FONT_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | |||
6 | class Font | ||
7 | { | ||
8 | public: | ||
9 | class Point | ||
10 | { | ||
11 | public: | ||
12 | int32_t x, y; | ||
13 | }; | ||
14 | |||
15 | class Glyph | ||
16 | { | ||
17 | public: | ||
18 | Glyph() : | ||
19 | pData( NULL ) | ||
20 | { } | ||
21 | ~Glyph() | ||
22 | { delete[] pData; } | ||
23 | Point pBox; | ||
24 | Point pOff; | ||
25 | Point pDevOff; | ||
26 | |||
27 | int iRowBytes; | ||
28 | uint8_t *pData; | ||
29 | }; | ||
30 | |||
31 | public: | ||
32 | Font( const char *sSrcFile ); | ||
33 | virtual ~Font(); | ||
34 | |||
35 | Glyph *get( char c ) { return pTable[(int32_t)c]; } | ||
36 | |||
37 | private: | ||
38 | Point pDefBox; | ||
39 | Point pDefOff; | ||
40 | int32_t iTableTop; | ||
41 | Glyph **pTable; | ||
42 | |||
43 | private: // Parser | ||
44 | class Parser | ||
45 | { | ||
46 | public: | ||
47 | Parser( const char *sSrcFile, Font &rFont ); | ||
48 | ~Parser(); | ||
49 | |||
50 | void parse(); | ||
51 | void getLine(); | ||
52 | void header(); | ||
53 | void properties(); | ||
54 | void characters(); | ||
55 | void character(); | ||
56 | |||
57 | private: | ||
58 | Font &rFont; | ||
59 | void *rawfh; | ||
60 | char *sLine; | ||
61 | bool bDone; | ||
62 | }; | ||
63 | }; | ||
64 | |||
65 | #endif | ||
diff --git a/src/image.cpp b/src/image.cpp new file mode 100644 index 0000000..384de9a --- /dev/null +++ b/src/image.cpp | |||
@@ -0,0 +1,143 @@ | |||
1 | #include "image.h" | ||
2 | #include "palette.h" | ||
3 | #include "font.h" | ||
4 | |||
5 | #include <stdlib.h> | ||
6 | #include <string.h> | ||
7 | #include <png.h> | ||
8 | |||
9 | Image::Image() : | ||
10 | iWidth( 0 ), | ||
11 | iHeight( 0 ), | ||
12 | pPix( NULL ) | ||
13 | { | ||
14 | } | ||
15 | |||
16 | Image::Image( int32_t iWidth, int32_t iHeight ) : | ||
17 | iWidth( iWidth ), | ||
18 | iHeight( iHeight ), | ||
19 | pPix( NULL ) | ||
20 | { | ||
21 | pPix = new uint8_t[iWidth*iHeight]; | ||
22 | clear(); | ||
23 | } | ||
24 | |||
25 | Image::~Image() | ||
26 | { | ||
27 | delete[] pPix; | ||
28 | } | ||
29 | |||
30 | void Image::clear( uint8_t uColor ) | ||
31 | { | ||
32 | memset( pPix, uColor, iWidth*iHeight ); | ||
33 | } | ||
34 | |||
35 | void Image::set( int32_t x, int32_t y, uint8_t iCol ) | ||
36 | { | ||
37 | if( x < 0 || y < 0 || x >= iWidth || y >= iHeight ) | ||
38 | return; | ||
39 | |||
40 | pPix[x+y*iWidth] = iCol; | ||
41 | } | ||
42 | |||
43 | void Image::save( const char *sPath, class Palette &rPal ) | ||
44 | { | ||
45 | uint8_t **pRows = new uint8_t*[iHeight]; | ||
46 | for( int r = 0; r < iHeight; r++ ) | ||
47 | { | ||
48 | pRows[r] = pPix+(iWidth*r); | ||
49 | } | ||
50 | |||
51 | png_structp png_ptr = png_create_write_struct( | ||
52 | PNG_LIBPNG_VER_STRING, NULL, NULL, NULL | ||
53 | ); | ||
54 | png_infop info_ptr = png_create_info_struct(png_ptr); | ||
55 | png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, | ||
56 | 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, | ||
57 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT | ||
58 | ); | ||
59 | png_color *pCol = new png_color[rPal.getCount()]; | ||
60 | for( int j = 0; j < rPal.getCount(); j++ ) | ||
61 | { | ||
62 | uint8_t r, g, b; | ||
63 | rPal.getColor( j, r, g, b ); | ||
64 | pCol[j].red = r; | ||
65 | pCol[j].green = g; | ||
66 | pCol[j].blue = b; | ||
67 | } | ||
68 | png_set_PLTE( png_ptr, info_ptr, pCol, rPal.getCount()); | ||
69 | |||
70 | png_set_rows( png_ptr, info_ptr, pRows ); | ||
71 | |||
72 | FILE *fp = fopen(sPath, "wb"); | ||
73 | if( fp == NULL ) | ||
74 | { | ||
75 | printf("Error opening file!\n"); | ||
76 | exit( 1 ); | ||
77 | } | ||
78 | |||
79 | png_init_io( png_ptr, fp ); | ||
80 | png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); | ||
81 | png_destroy_write_struct( &png_ptr, &info_ptr ); | ||
82 | fclose( fp ); | ||
83 | |||
84 | delete[] pCol; | ||
85 | delete[] pRows; | ||
86 | } | ||
87 | |||
88 | void Image::drawText( class Font &rFnt, int32_t x, int32_t y, uint8_t uColor, | ||
89 | const char *sText ) | ||
90 | { | ||
91 | for( const char *s = sText; *s; s++ ) | ||
92 | { | ||
93 | Font::Glyph *pGlyph = rFnt.get( *s ); | ||
94 | if( pGlyph == NULL ) | ||
95 | continue; | ||
96 | |||
97 | for( int cy = 0; cy < pGlyph->pBox.y; cy++ ) | ||
98 | { | ||
99 | for( int cx = 0; cx < pGlyph->pBox.x; cx++ ) | ||
100 | { | ||
101 | int bit = 1<<(7-(cx%8)); | ||
102 | int byte = cx/8; | ||
103 | if( pGlyph->pData[byte+cy*pGlyph->iRowBytes]&bit ) | ||
104 | set( x+cx, y+cy-pGlyph->pBox.y-pGlyph->pOff.y, uColor ); | ||
105 | } | ||
106 | } | ||
107 | x += pGlyph->pDevOff.x; | ||
108 | y += pGlyph->pDevOff.y; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | void Image::drawLine( int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t uColor ) | ||
113 | { | ||
114 | if( x1 == x2 ) | ||
115 | { | ||
116 | // Vertical line, easy | ||
117 | if( y2 < y1 ) | ||
118 | { | ||
119 | int32_t r = y2; | ||
120 | y2 = y1; | ||
121 | y1 = r; | ||
122 | } | ||
123 | for( int j = y1; j <= y2; j++ ) | ||
124 | { | ||
125 | set( x1, j, uColor ); | ||
126 | } | ||
127 | } | ||
128 | else if( y1 == y2 ) | ||
129 | { | ||
130 | // Horizontal line, easy | ||
131 | if( x2 < x1 ) | ||
132 | { | ||
133 | int32_t r = x2; | ||
134 | x2 = x1; | ||
135 | x1 = r; | ||
136 | } | ||
137 | for( int j = x1; j <= x2; j++ ) | ||
138 | { | ||
139 | set( j, y1, uColor ); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
diff --git a/src/image.h b/src/image.h new file mode 100644 index 0000000..cdc13e0 --- /dev/null +++ b/src/image.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef IMAGE_H | ||
2 | #define IMAGE_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | |||
6 | class Image | ||
7 | { | ||
8 | public: | ||
9 | Image(); | ||
10 | Image( int32_t iWidth, int32_t iHeight ); | ||
11 | virtual ~Image(); | ||
12 | |||
13 | void clear( uint8_t uColor=0 ); | ||
14 | void set( int32_t x, int32_t y, uint8_t iCol ); | ||
15 | |||
16 | void save( const char *sPath, class Palette &rPal ); | ||
17 | void drawText( class Font &rFnt, int32_t x, int32_t y, uint8_t uColor, | ||
18 | const char *sText ); | ||
19 | void drawLine( int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t uColor ); | ||
20 | |||
21 | private: | ||
22 | int32_t iWidth; | ||
23 | int32_t iHeight; | ||
24 | uint8_t *pPix; | ||
25 | }; | ||
26 | |||
27 | #endif | ||
diff --git a/src/main.cpp b/src/main.cpp index ef3f3de..00dfc8b 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -10,8 +10,24 @@ | |||
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <time.h> | 11 | #include <time.h> |
12 | 12 | ||
13 | #include "image.h" | ||
14 | #include "palette.h" | ||
15 | #include "font.h" | ||
16 | |||
13 | int main( int argc, char *argv[] ) | 17 | int main( int argc, char *argv[] ) |
14 | { | 18 | { |
19 | /* | ||
20 | Image im( 400, 400 ); | ||
21 | Font f("ter-u12n.bdf"); | ||
22 | Palette pl; | ||
23 | pl.addColor( 0, 0, 0 ); | ||
24 | pl.addColor( 255, 0, 0 ); | ||
25 | pl.addColor( 0, 0, 255 ); | ||
26 | im.drawLine( 0, 12, 399, 12, 2 ); | ||
27 | im.drawText( f, 12, 12, 1, "Hello World!yqjm (01234,56789)"); | ||
28 | im.save("test.png", pl); | ||
29 | return 0; | ||
30 | */ | ||
15 | srand( time( NULL ) ); | 31 | srand( time( NULL ) ); |
16 | 32 | ||
17 | if( argc <= 2 ) | 33 | if( argc <= 2 ) |
diff --git a/src/palette.cpp b/src/palette.cpp new file mode 100644 index 0000000..0e3a3b1 --- /dev/null +++ b/src/palette.cpp | |||
@@ -0,0 +1,32 @@ | |||
1 | #include "palette.h" | ||
2 | |||
3 | #include <string.h> | ||
4 | |||
5 | Palette::Palette() : | ||
6 | iCount( 0 ), | ||
7 | piChannels( NULL ) | ||
8 | { | ||
9 | piChannels = new uint8_t[256*3]; | ||
10 | memset( piChannels, 0, 256*3 ); | ||
11 | } | ||
12 | |||
13 | Palette::~Palette() | ||
14 | { | ||
15 | delete[] piChannels; | ||
16 | } | ||
17 | |||
18 | int32_t Palette::addColor( uint8_t iRed, uint8_t iGreen, uint8_t iBlue ) | ||
19 | { | ||
20 | piChannels[iCount*3] = iRed; | ||
21 | piChannels[iCount*3+1] = iGreen; | ||
22 | piChannels[iCount*3+2] = iBlue; | ||
23 | return iCount++; | ||
24 | } | ||
25 | |||
26 | void Palette::getColor( int32_t iIdx, uint8_t &iRed, uint8_t &iGreen, | ||
27 | uint8_t &iBlue ) | ||
28 | { | ||
29 | iRed = piChannels[iIdx*3]; | ||
30 | iGreen = piChannels[iIdx*3+1]; | ||
31 | iBlue = piChannels[iIdx*3+2]; | ||
32 | } | ||
diff --git a/src/palette.h b/src/palette.h new file mode 100644 index 0000000..3fb176a --- /dev/null +++ b/src/palette.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef PALETTE_H | ||
2 | #define PALETTE_H | ||
3 | |||
4 | #include <stdint.h> | ||
5 | |||
6 | class Palette | ||
7 | { | ||
8 | public: | ||
9 | Palette(); | ||
10 | virtual ~Palette(); | ||
11 | |||
12 | int32_t addColor( uint8_t iRed, uint8_t iGreen, uint8_t iBlue ); | ||
13 | int32_t getCount() const { return iCount; } | ||
14 | void getColor( int32_t iIdx, uint8_t &iRed, uint8_t &iGreen, | ||
15 | uint8_t &iBlue ); | ||
16 | |||
17 | private: | ||
18 | int32_t iCount; | ||
19 | uint8_t *piChannels; | ||
20 | }; | ||
21 | |||
22 | #endif | ||
diff --git a/src/renderpng.cpp b/src/renderpng.cpp index 21d35ba..6ff9fbe 100644 --- a/src/renderpng.cpp +++ b/src/renderpng.cpp | |||
@@ -3,11 +3,15 @@ | |||
3 | #include "map.h" | 3 | #include "map.h" |
4 | #include "cell.h" | 4 | #include "cell.h" |
5 | 5 | ||
6 | #include "image.h" | ||
7 | #include "palette.h" | ||
8 | #include "font.h" | ||
9 | |||
6 | #include <math.h> | 10 | #include <math.h> |
7 | #include <string.h> | 11 | #include <string.h> |
8 | #include <stdint.h> | 12 | #include <stdint.h> |
9 | #include <stdlib.h> | 13 | #include <stdlib.h> |
10 | #include <png.h> | 14 | #include <stdio.h> |
11 | 15 | ||
12 | RenderPng::RenderPng( Map &rMap ) : | 16 | RenderPng::RenderPng( Map &rMap ) : |
13 | rMap( rMap ) | 17 | rMap( rMap ) |
@@ -25,16 +29,18 @@ void RenderPng::render() | |||
25 | if( iDims > 2 ) | 29 | if( iDims > 2 ) |
26 | iSize = (int)ceil(sqrt((rMap.getDims()-2)*2)); | 30 | iSize = (int)ceil(sqrt((rMap.getDims()-2)*2)); |
27 | 31 | ||
28 | int iBufWidth = ((iSize+1)*rMap.getSize( 0 )+1)*5; | 32 | int iCellSize = 11; |
29 | int iBufHeight = ((iSize+1)*rMap.getSize( 1 )+1)*5; | 33 | int iCellMid = iCellSize/2; |
30 | int iBufSize = iBufWidth*iBufHeight; | 34 | int iBufWidth = ((iSize+1)*rMap.getSize( 0 )+1)*iCellSize; |
31 | uint8_t *pBuf = new uint8_t[iBufSize]; | 35 | int iBufHeight = ((iSize+1)*rMap.getSize( 1 )+1)*iCellSize+12; |
32 | uint8_t **pRows = new uint8_t*[iBufHeight]; | 36 | int ox = 0; |
33 | for( int r = 0; r < iBufHeight; r++ ) | 37 | int oy = 12; |
34 | { | 38 | Image im( iBufWidth, iBufHeight ); |
35 | pRows[r] = pBuf+(iBufWidth*r); | 39 | Font fnt("ter-u12n.bdf"); |
36 | } | 40 | im.clear( 1 ); |
37 | memset( pBuf, 1, iBufSize ); | 41 | Palette pal; |
42 | pal.addColor( 0, 0, 0 ); | ||
43 | pal.addColor( 255, 255, 255 ); | ||
38 | 44 | ||
39 | Position p( iDims ); | 45 | Position p( iDims ); |
40 | for(;;) | 46 | for(;;) |
@@ -50,86 +56,138 @@ void RenderPng::render() | |||
50 | if( (iRow == 0 || iRow == iSize+1) && | 56 | if( (iRow == 0 || iRow == iSize+1) && |
51 | (iCol == 0 || iCol == iSize+1) ) | 57 | (iCol == 0 || iCol == iSize+1) ) |
52 | { | 58 | { |
53 | pRows[(y+iRow)*5+2][(x+iCol)*5+2] = 0; | 59 | im.set( |
60 | ox+(x+iCol)*iCellSize+iCellMid, | ||
61 | oy+(y+iRow)*iCellSize+iCellMid, | ||
62 | 0 | ||
63 | ); | ||
54 | if( iRow == 0 && iCol == 0 ) | 64 | if( iRow == 0 && iCol == 0 ) |
55 | { | 65 | { |
56 | if( (iWalls&(1<<2)) == 0 ) | 66 | if( (iWalls&(1<<2)) == 0 ) |
57 | { | 67 | { |
58 | for( int i = 0; i < 3; i++ ) | 68 | for( int i = 0; i < iCellMid+1; i++ ) |
59 | pRows[(y+iRow)*5+2][(x+iCol)*5+i+3] = 0; | 69 | im.set( |
70 | ox+(x+iCol)*iCellSize+i+iCellMid+1, | ||
71 | oy+(y+iRow)*iCellSize+iCellMid, | ||
72 | 0 | ||
73 | ); | ||
60 | } | 74 | } |
61 | if( (iWalls&(1<<0)) == 0 ) | 75 | if( (iWalls&(1<<0)) == 0 ) |
62 | { | 76 | { |
63 | for( int i = 0; i < 3; i++ ) | 77 | for( int i = 0; i < iCellMid+1; i++ ) |
64 | pRows[(y+iRow)*5+i+3][(x+iCol)*5+2] = 0; | 78 | im.set( |
79 | ox+(x+iCol)*iCellSize+iCellMid, | ||
80 | oy+(y+iRow)*iCellSize+i+iCellMid+1, | ||
81 | 0 | ||
82 | ); | ||
65 | } | 83 | } |
66 | } | 84 | } |
67 | else if( iRow == 0 && iCol == iSize+1 ) | 85 | else if( iRow == 0 && iCol == iSize+1 ) |
68 | { | 86 | { |
69 | if( (iWalls&(1<<2)) == 0 ) | 87 | if( (iWalls&(1<<2)) == 0 ) |
70 | { | 88 | { |
71 | for( int i = 0; i < 3; i++ ) | 89 | for( int i = 0; i < iCellMid+1; i++ ) |
72 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | 90 | im.set( |
91 | ox+(x+iCol)*iCellSize+i, | ||
92 | oy+(y+iRow)*iCellSize+iCellMid, | ||
93 | 0 | ||
94 | ); | ||
73 | } | 95 | } |
74 | if( (iWalls&(1<<1)) == 0 ) | 96 | if( (iWalls&(1<<1)) == 0 ) |
75 | { | 97 | { |
76 | for( int i = 0; i < 3; i++ ) | 98 | for( int i = 0; i < iCellMid+1; i++ ) |
77 | pRows[(y+iRow)*5+i+3][(x+iCol)*5+2] = 0; | 99 | im.set( |
100 | ox+(x+iCol)*iCellSize+iCellMid, | ||
101 | oy+(y+iRow)*iCellSize+i+iCellMid+1, | ||
102 | 0 | ||
103 | ); | ||
78 | } | 104 | } |
79 | } | 105 | } |
80 | else if( iRow == iSize+1 && iCol == 0 ) | 106 | else if( iRow == iSize+1 && iCol == 0 ) |
81 | { | 107 | { |
82 | if( (iWalls&(1<<3)) == 0 ) | 108 | if( (iWalls&(1<<3)) == 0 ) |
83 | { | 109 | { |
84 | for( int i = 0; i < 3; i++ ) | 110 | for( int i = 0; i < iCellMid+1; i++ ) |
85 | pRows[(y+iRow)*5+2][(x+iCol)*5+i+3] = 0; | 111 | im.set( |
112 | ox+(x+iCol)*iCellSize+i+iCellMid+1, | ||
113 | oy+(y+iRow)*iCellSize+iCellMid, | ||
114 | 0 | ||
115 | ); | ||
86 | } | 116 | } |
87 | if( (iWalls&(1<<0)) == 0 ) | 117 | if( (iWalls&(1<<0)) == 0 ) |
88 | { | 118 | { |
89 | for( int i = 0; i < 3; i++ ) | 119 | for( int i = 0; i < iCellMid+1; i++ ) |
90 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | 120 | im.set( |
121 | ox+(x+iCol)*iCellSize+iCellMid, | ||
122 | oy+(y+iRow)*iCellSize+i, | ||
123 | 0 | ||
124 | ); | ||
91 | } | 125 | } |
92 | } | 126 | } |
93 | else if( iRow == iSize+1 && iCol == iSize+1 ) | 127 | else if( iRow == iSize+1 && iCol == iSize+1 ) |
94 | { | 128 | { |
95 | if( (iWalls&(1<<3)) == 0 ) | 129 | if( (iWalls&(1<<3)) == 0 ) |
96 | { | 130 | { |
97 | for( int i = 0; i < 3; i++ ) | 131 | for( int i = 0; i < iCellMid+1; i++ ) |
98 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | 132 | im.set( |
133 | ox+(x+iCol)*iCellSize+i, | ||
134 | oy+(y+iRow)*iCellSize+iCellMid, | ||
135 | 0 | ||
136 | ); | ||
99 | } | 137 | } |
100 | if( (iWalls&(1<<1)) == 0 ) | 138 | if( (iWalls&(1<<1)) == 0 ) |
101 | { | 139 | { |
102 | for( int i = 0; i < 3; i++ ) | 140 | for( int i = 0; i < iCellMid+1; i++ ) |
103 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | 141 | im.set( |
142 | ox+(x+iCol)*iCellSize+iCellMid, | ||
143 | oy+(y+iRow)*iCellSize+i, | ||
144 | 0 | ||
145 | ); | ||
104 | } | 146 | } |
105 | } | 147 | } |
106 | } | 148 | } |
107 | else if( iRow == 0 && (iWalls&(1<<2)) == 0 ) | 149 | else if( iRow == 0 && (iWalls&(1<<2)) == 0 ) |
108 | { | 150 | { |
109 | for( int i = 0; i < 5; i++ ) | 151 | for( int i = 0; i < iCellSize; i++ ) |
110 | { | 152 | { |
111 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | 153 | im.set( |
154 | ox+(x+iCol)*iCellSize+i, | ||
155 | oy+(y+iRow)*iCellSize+iCellMid, | ||
156 | 0 | ||
157 | ); | ||
112 | } | 158 | } |
113 | } | 159 | } |
114 | else if( iRow == iSize+1 && (iWalls&(1<<3)) == 0 ) | 160 | else if( iRow == iSize+1 && (iWalls&(1<<3)) == 0 ) |
115 | { | 161 | { |
116 | for( int i = 0; i < 5; i++ ) | 162 | for( int i = 0; i < iCellSize; i++ ) |
117 | { | 163 | { |
118 | pRows[(y+iRow)*5+2][(x+iCol)*5+i] = 0; | 164 | im.set( |
165 | ox+(x+iCol)*iCellSize+i, | ||
166 | oy+(y+iRow)*iCellSize+iCellMid, | ||
167 | 0 | ||
168 | ); | ||
119 | } | 169 | } |
120 | } | 170 | } |
121 | else if( iCol == 0 && (iWalls&(1<<0)) == 0 ) | 171 | else if( iCol == 0 && (iWalls&(1<<0)) == 0 ) |
122 | { | 172 | { |
123 | for( int i = 0; i < 5; i++ ) | 173 | for( int i = 0; i < iCellSize; i++ ) |
124 | { | 174 | { |
125 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | 175 | im.set( |
176 | ox+(x+iCol)*iCellSize+iCellMid, | ||
177 | oy+(y+iRow)*iCellSize+i, | ||
178 | 0 | ||
179 | ); | ||
126 | } | 180 | } |
127 | } | 181 | } |
128 | else if( iCol == iSize+1 && (iWalls&(1<<1)) == 0 ) | 182 | else if( iCol == iSize+1 && (iWalls&(1<<1)) == 0 ) |
129 | { | 183 | { |
130 | for( int i = 0; i < 5; i++ ) | 184 | for( int i = 0; i < iCellSize; i++ ) |
131 | { | 185 | { |
132 | pRows[(y+iRow)*5+i][(x+iCol)*5+2] = 0; | 186 | im.set( |
187 | ox+(x+iCol)*iCellSize+iCellMid, | ||
188 | oy+(y+iRow)*iCellSize+i, | ||
189 | 0 | ||
190 | ); | ||
133 | } | 191 | } |
134 | } | 192 | } |
135 | } | 193 | } |
@@ -142,43 +200,73 @@ void RenderPng::render() | |||
142 | int d = j*2+side; | 200 | int d = j*2+side; |
143 | if( iWalls&(1<<d) ) | 201 | if( iWalls&(1<<d) ) |
144 | { | 202 | { |
145 | int iSubX = (x+1+((d-4)%iSize))*5; | 203 | int iSubX = (x+1+((d-4)%iSize))*iCellSize; |
146 | int iSubY = (y+1+((d-4)/iSize))*5; | 204 | int iSubY = (y+1+((d-4)/iSize))*iCellSize; |
147 | // | 205 | |
148 | // char &c = buf[x+1+iSubX+(y+1+iSubY)*iBufWidth]; | ||
149 | // c = cPassages[d]; | ||
150 | switch( d ) | 206 | switch( d ) |
151 | { | 207 | { |
152 | case 4: | 208 | case 4: |
153 | pRows[iSubY+1][iSubX+2] = 0; | 209 | im.set( ox+iSubX+iCellMid, oy+iSubY+1, 0 ); |
154 | pRows[iSubY+2][iSubX+1] = 0; | 210 | for( int m = 0; m < iCellMid; m++ ) |
155 | pRows[iSubY+2][iSubX+3] = 0; | 211 | { |
156 | pRows[iSubY+3][iSubX+0] = 0; | 212 | im.set( ox+iSubX+m, oy+iSubY+iCellMid-m+1, 0 ); |
157 | pRows[iSubY+3][iSubX+4] = 0; | 213 | im.set( ox+iSubX+iCellMid+m+1, oy+iSubY+m+2, 0 ); |
214 | } | ||
215 | /* | ||
216 | im.set( iSubX+2, iSubY+1, 0 ); | ||
217 | im.set( iSubX+1, iSubY+2, 0 ); | ||
218 | im.set( iSubX+3, iSubY+2, 0 ); | ||
219 | im.set( iSubX+0, iSubY+3, 0 ); | ||
220 | im.set( iSubX+4, iSubY+3, 0 ); | ||
221 | */ | ||
158 | break; | 222 | break; |
159 | 223 | ||
160 | case 5: | 224 | case 5: |
161 | pRows[iSubY+3][iSubX+2] = 0; | 225 | im.set( ox+iSubX+iCellMid, oy+iSubY+iCellSize-2, 0 ); |
162 | pRows[iSubY+2][iSubX+1] = 0; | 226 | for( int m = 0; m < iCellMid; m++ ) |
163 | pRows[iSubY+2][iSubX+3] = 0; | 227 | { |
164 | pRows[iSubY+1][iSubX+0] = 0; | 228 | im.set( ox+iSubX+m, oy+iSubY+iCellMid+m-1, 0 ); |
165 | pRows[iSubY+1][iSubX+4] = 0; | 229 | im.set( ox+iSubX+iCellMid+m+1, oy+iSubY+iCellSize-m-3, 0 ); |
230 | } | ||
231 | /* | ||
232 | im.set( iSubX+2, iSubY+3, 0 ); | ||
233 | im.set( iSubX+1, iSubY+2, 0 ); | ||
234 | im.set( iSubX+3, iSubY+2, 0 ); | ||
235 | im.set( iSubX+0, iSubY+1, 0 ); | ||
236 | im.set( iSubX+4, iSubY+1, 0 ); | ||
237 | */ | ||
166 | break; | 238 | break; |
167 | 239 | ||
168 | case 6: | 240 | case 6: |
169 | pRows[iSubY+2][iSubX+1] = 0; | 241 | im.set( ox+iSubX+1, oy+iSubY+iCellMid, 0 ); |
170 | pRows[iSubY+1][iSubX+2] = 0; | 242 | for( int m = 0; m < iCellMid; m++ ) |
171 | pRows[iSubY+3][iSubX+2] = 0; | 243 | { |
172 | pRows[iSubY+0][iSubX+3] = 0; | 244 | im.set( ox+iSubX+iCellMid-m+1, oy+iSubY+m, 0 ); |
173 | pRows[iSubY+4][iSubX+3] = 0; | 245 | im.set( ox+iSubX+m+2, oy+iSubY+iCellMid+m+1, 0 ); |
246 | } | ||
247 | /* | ||
248 | im.set( iSubX+1, iSubY+2, 0 ); | ||
249 | im.set( iSubX+2, iSubY+1, 0 ); | ||
250 | im.set( iSubX+2, iSubY+3, 0 ); | ||
251 | im.set( iSubX+3, iSubY+0, 0 ); | ||
252 | im.set( iSubX+3, iSubY+4, 0 ); | ||
253 | */ | ||
174 | break; | 254 | break; |
175 | 255 | ||
176 | case 7: | 256 | case 7: |
177 | pRows[iSubY+2][iSubX+3] = 0; | 257 | im.set( ox+iSubX+iCellSize-2, oy+iSubY+iCellMid, 0 ); |
178 | pRows[iSubY+1][iSubX+2] = 0; | 258 | for( int m = 0; m < iCellMid; m++ ) |
179 | pRows[iSubY+3][iSubX+2] = 0; | 259 | { |
180 | pRows[iSubY+0][iSubX+1] = 0; | 260 | im.set( ox+iSubX+iCellMid+m-1, oy+iSubY+m, 0 ); |
181 | pRows[iSubY+4][iSubX+1] = 0; | 261 | im.set( ox+iSubX+iCellSize-m-3, oy+iSubY+iCellMid+m+1, 0 ); |
262 | } | ||
263 | /* | ||
264 | im.set( iSubX+3, iSubY+2, 0 ); | ||
265 | im.set( iSubX+2, iSubY+1, 0 ); | ||
266 | im.set( iSubX+2, iSubY+3, 0 ); | ||
267 | im.set( iSubX+1, iSubY+0, 0 ); | ||
268 | im.set( iSubX+1, iSubY+4, 0 ); | ||
269 | */ | ||
182 | break; | 270 | break; |
183 | } | 271 | } |
184 | } | 272 | } |
@@ -187,6 +275,7 @@ void RenderPng::render() | |||
187 | 275 | ||
188 | int iDim; | 276 | int iDim; |
189 | char fname[1024]; | 277 | char fname[1024]; |
278 | char title[1024]; | ||
190 | for( iDim = 0; iDim < iDims; iDim++ ) | 279 | for( iDim = 0; iDim < iDims; iDim++ ) |
191 | { | 280 | { |
192 | if( ++p[iDim] < rMap.getSize( iDim ) ) | 281 | if( ++p[iDim] < rMap.getSize( iDim ) ) |
@@ -200,43 +289,25 @@ void RenderPng::render() | |||
200 | char buf[1024]; | 289 | char buf[1024]; |
201 | sprintf( buf, "-%d", rMap.getSize(2)-p[2] ); | 290 | sprintf( buf, "-%d", rMap.getSize(2)-p[2] ); |
202 | strcat( fname, buf ); | 291 | strcat( fname, buf ); |
292 | sprintf( buf, "Floor: %d", rMap.getSize(2)-p[2] ); | ||
293 | strcpy( title, buf ); | ||
203 | for( int j = 3; j < iDims; j++ ) | 294 | for( int j = 3; j < iDims; j++ ) |
204 | { | 295 | { |
205 | sprintf( buf, "-%d", rMap.getSize(j)-p[j] ); | 296 | sprintf( buf, "-%d", rMap.getSize(j)-p[j] ); |
206 | strcat( fname, buf ); | 297 | strcat( fname, buf ); |
298 | sprintf( buf, ", %d", rMap.getSize(j)-p[j] ); | ||
299 | strcat( title, buf ); | ||
207 | } | 300 | } |
208 | } | 301 | } |
302 | else | ||
303 | title[0] = '\0'; | ||
304 | im.drawText( fnt, ox, oy-2, 0, title ); | ||
209 | strcat( fname, ".png"); | 305 | strcat( fname, ".png"); |
210 | printf("Output: %s\n", fname ); | 306 | printf("Output: %s\n", fname ); |
211 | 307 | ||
212 | png_structp png_ptr = png_create_write_struct( | 308 | im.save( fname, pal ); |
213 | PNG_LIBPNG_VER_STRING, NULL, NULL, NULL | ||
214 | ); | ||
215 | png_infop info_ptr = png_create_info_struct(png_ptr); | ||
216 | png_set_IHDR(png_ptr, info_ptr, iBufWidth, iBufHeight, | ||
217 | 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, | ||
218 | PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT | ||
219 | ); | ||
220 | png_color col[2]; | ||
221 | col[0].red = col[0].green = col[0].blue = 0; | ||
222 | col[1].red = col[1].green = col[1].blue = 255; | ||
223 | png_set_PLTE( png_ptr, info_ptr, col, 2); | ||
224 | |||
225 | png_set_rows( png_ptr, info_ptr, pRows ); | ||
226 | |||
227 | FILE *fp = fopen(fname, "wb"); | ||
228 | if( fp == NULL ) | ||
229 | { | ||
230 | printf("Error opening file!\n"); | ||
231 | exit( 1 ); | ||
232 | } | ||
233 | |||
234 | png_init_io( png_ptr, fp ); | ||
235 | png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); | ||
236 | png_destroy_write_struct( &png_ptr, &info_ptr ); | ||
237 | fclose( fp ); | ||
238 | 309 | ||
239 | memset( pBuf, 1, iBufSize ); | 310 | im.clear( 1 ); |
240 | } | 311 | } |
241 | } | 312 | } |
242 | if( iDim == iDims ) | 313 | if( iDim == iDims ) |
@@ -260,7 +331,5 @@ void RenderPng::render() | |||
260 | } | 331 | } |
261 | // printf(buf); | 332 | // printf(buf); |
262 | 333 | ||
263 | delete[] pBuf; | ||
264 | delete[] pRows; | ||
265 | } | 334 | } |
266 | 335 | ||