Tile encoder/decoder

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Drag
Posts: 1350
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Tile encoder/decoder

Post by Drag »

Ah, interesting. So both methods explore all possible permutations, just with different scopes? The use of Dijkstra's algorithm is pretty clever, I overlook that a lot. Tokumaru's method (a greedy algorithm) is what I would've come up with.

This question is because several years ago, Disch was working on a compressor for a scheme like the one in Kirby's Adventure, where there's several different compression algorithms all working together, but a challenge was figuring out how to determine which permutation of compressed chunks yielded the best ratio. It's funny to see that challenge cropping up again in this encoder. :P
Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Re: Tile encoder/decoder

Post by Bisqwit »

Drag wrote:It's funny to see that challenge cropping up again in this encoder. :P
It occurs pretty often in the theme of compression. Pretty much every compressor that has two or more ways of encoding same things runs into this topic. It is also the first time that I use Dijkstra's algorithm in this context.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Tile encoder/decoder

Post by tokumaru »

Drag wrote:Tokumaru's method (a greedy algorithm) is what I would've come up with.
A strictly greedy algorithm would select the best length for the current block regardless of what comes next. It's been a long time, but if I'm not mistaken, I kept increasing the length of the current block until the compression ratio started to drop, and then I tested how well the next block compressed for all possible lengths of the first block, from the calculated maximum down to 1, and picked the best cimbination. Or something like that! :mrgreen:
Bisqwit
Posts: 248
Joined: Fri Oct 14, 2011 1:09 am

Re: Tile encoder/decoder

Post by Bisqwit »

Update: I added a CA65-compatible decompressor module and a test ROM.

Differences to Tokumaru's decompressor: At feature parity,
Code size is $EE bytes (2 bytes smaller) $D9 bytes (23 bytes smaller)
RAM usage is 19 bytes (13 bytes smaller)
Speed differences not measured.

I also added support for compressing and decompressing from/to stdin/stdout.
Download: http://bisqwit.iki.fi/source/tokumaru.html

If the compression format was changed a little, the decompressor could be made even smaller without sacrificing compression ratio.
Namely, inverting the meaning of the first color bit in the tile data, so that there will be fewer special cases in the decompression code.

EDIT: Yeah, I just went ahead and implemented that extension as an optional format (-e option). The decompressor is now $E7 bytes for extended format, $EC bytes for non-extended format.
EDIT 2: $DE and $E3 bytes now respectively.


Image

EDIT: Decided to make various settings user-adjustable.

Code: Select all

;  USER-ADJUSTABLE SETTINGS

EXTENDED_FORMAT=1
; ^ Set to 1 if you compressed with -e.
;   Makes decompressor 5 bytes shorter with very minor speed impact.
;   If you compressed with -e3, set to 3. If with -e2, set to 2.
;   +2 makes decompresser 1 byte smaller, but consumes 2 more bytes of RAM.

FASTER=0
; ^ Set to 1 if you want faster code.
;   It will cause ReadBit to be inlined, and some other assorted changes.
;   Makes decompressor 37 bytes longer, but about 10 cycles faster per bit.

RAMBUFFER=1
; ^ Set to 1 if you can spare 7 more bytes of zero-page RAM.
;   Makes decompressor 6-7 bytes shorter, and 8-10 cycles faster per tile.
;   If FASTER=1, makes 5-6 bytes shorter, and 28-30 cycles faster per tile.

RAMTEMP=1
; ^ Set to 1 if you can spare 3 more bytes of zero-page RAM.
;   Makes decompressor 1-2 bytes longer, but 1.5 cycles faster per bit.

; SUMMARY -- SIZE PROFILE FOR DECOMPRESSOR:
;
;  EXTENDED_FORMAT FASTER RAMBUFFER RAMTEMP   CODE SIZE   RAM USE   STACK USE  RUNTIME
;                1      0         1       0   $0D4 (212)  19 bytes   5 bytes   1161959 cycles
;                1      0         1       1   $0D5 (213)  22 bytes   2 bytes   1144551 cycles
;                0      0         1       0   $0D9 (217)  19 bytes   5 bytes   1159744 cycles
;                1      0         0       0   $0DA (218)  12 bytes  12 bytes   1162215 cycles
;                0      0         1       1   $0DA (218)  22 bytes   2 bytes   1142336 cycles
;                1      0         0       1   $0DC (220)  15 bytes   9 bytes   1145319 cycles
;                0      0         0       0   $0DF (223)  12 bytes  12 bytes   1161792 cycles
;                0      0         0       1   $0E1 (225)  15 bytes   9 bytes   1144896 cycles
;                1      1         1       0   $0F9 (249)  19 bytes   5 bytes   981134 cycles
;                1      1         1       1   $0FA (250)  22 bytes   2 bytes   963726 cycles
;                1      1         0       0   $0FE (254)  12 bytes  12 bytes   968820 cycles
;                1      1         0       1   $100 (256)  15 bytes   9 bytes   965518 cycles
;                0      1         1       0   $102 (258)  19 bytes   5 bytes   970325 cycles
;                0      1         1       1   $103 (259)  22 bytes   2 bytes   952917 cycles
;                0      1         0       0   $107 (263)  12 bytes  12 bytes   962021 cycles
;                0      1         0       1   $109 (265)  15 bytes   9 bytes   954709 cycles
;
; END OF USER-ADJUSTABLE SETTINGS
The "runtime" column lists the number of cycles it took to decompress the first 4096 bytes ($1000) of the CHR-RAM data for the demo included with the program. Stack is the number of bytes it reserved from stack in addition to the function call frame; RAM and code size are automatically gathered from the linker statistics.

EDIT: Version 1.3.0 released. Updated the stats again. The decompressor got smaller, again.
User avatar
pubby
Posts: 555
Joined: Thu Mar 31, 2016 11:15 am

Re: Tile encoder/decoder

Post by pubby »

For curiosity's sake, I compressed some chr files using jbigkit to see how it stacks up to Tokumaru compression.

Here are the compression ratios I got (uncompressed size / compressed size):

Code: Select all

Tokumaru: 1.83
jbig85:   1.84
jbig:     2.04
And here are the files I tested: battlekid.chr geminim.chr gemventure.ch dpadhero.chr cmc80s.chr

Tokumaru compression is as good as jbig85, but slightly worse than fully-featured jbig. I don't think jbig is worth implementing on the NES though. It's much too complicated and requires too much RAM.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Tile encoder/decoder

Post by Bregalad »

I wanted to try this compression but I cannot manage to compile it with mingw. I could try again with Linux, but nonetheless, there's still no reason I would not be allowed to compile this with mingw. Requiring C++14 which was only very recently imported in gcc is not the brightest idea, either.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Tile encoder/decoder

Post by tepples »

What error do you get in MinGW? Do you know how to copy and paste the error from MinGW?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Tile encoder/decoder

Post by Bregalad »

I get

Code: Select all

tokumaru.cc:37:18: fatal error: omp.h: No such file or directory
 # include <omp.h>
                  ^
compilation terminated.
make: *** [tokumaru] Error 1
After commneting out those 3 lines in "tokumaru.cc":

Code: Select all

#ifdef _OPENMP
# include <omp.h>
#endif
I get :

Code: Select all

In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:59:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:201:11: error: '::lldiv_t' has not been declared
   using ::lldiv_t;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:207:11: error: '::_Exit' has not been declared
   using ::_Exit;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:211:11: error: '::llabs' has not been declared
   using ::llabs;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:213:10: error: 'lldiv_t' does not name a type
   inline lldiv_t
          ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:217:11: error: '::lldiv' has not been declared
   using ::lldiv;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:228:11: error: '::atoll' has not been declared
   using ::atoll;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:229:11: error: '::strtoll' has not been declared
   using ::strtoll;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:230:11: error: '::strtoull' has not been declared
   using ::strtoull;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:232:11: error: '::strtof' has not been declared
   using ::strtof;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:233:11: error: '::strtold' has not been declared
   using ::strtold;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:241:22: error: '__gnu_cxx::lldiv_t' has not been declared
   using ::__gnu_cxx::lldiv_t;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:243:22: error: '__gnu_cxx::_Exit' has not been declared
   using ::__gnu_cxx::_Exit;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:245:22: error: '__gnu_cxx::llabs' has not been declared
   using ::__gnu_cxx::llabs;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:246:22: error: '__gnu_cxx::div' has not been declared
   using ::__gnu_cxx::div;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:247:22: error: '__gnu_cxx::lldiv' has not been declared
   using ::__gnu_cxx::lldiv;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:249:22: error: '__gnu_cxx::atoll' has not been declared
   using ::__gnu_cxx::atoll;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:250:22: error: '__gnu_cxx::strtof' has not been declared
   using ::__gnu_cxx::strtof;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:251:22: error: '__gnu_cxx::strtoll' has not been declared
   using ::__gnu_cxx::strtoll;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:252:22: error: '__gnu_cxx::strtoull' has not been declared
   using ::__gnu_cxx::strtoull;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdlib:253:22: error: '__gnu_cxx::strtold' has not been declared
   using ::__gnu_cxx::strtold;
                      ^
In file included from c:\mingw\include\wchar.h:208:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:44,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\postypes.h:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\include\sys/stat.h:173:14: error: '_dev_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: '_ino_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: '_mode_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: '_dev_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: '_off_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: 'time_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: 'time_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:173:14: error: 'time_t' does not name a type
 struct _stat __struct_stat_defined( _off_t, time_t );
              ^
c:\mingw\include\sys/stat.h:180:13: error: '_dev_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: '_ino_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: '_mode_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: '_dev_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: '_off_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: 'time_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: 'time_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:180:13: error: 'time_t' does not name a type
 struct stat __struct_stat_defined( _off_t, time_t );
             ^
c:\mingw\include\sys/stat.h:188:17: error: '_dev_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: '_ino_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: '_mode_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: '_dev_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: '__off64_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: 'time_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: 'time_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:188:17: error: 'time_t' does not name a type
 struct _stati64 __struct_stat_defined( __off64_t, time_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '_dev_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '_ino_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '_mode_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '_dev_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '__off64_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '__time64_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '__time64_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
c:\mingw\include\sys/stat.h:195:17: error: '__time64_t' does not name a type
 struct __stat64 __struct_stat_defined( __off64_t, __time64_t );
                 ^
In file included from c:\mingw\include\wchar.h:233:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:44,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\postypes.h:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\include\io.h:335:21: error: 'time_t' does not name a type
 struct _wfinddata_t __struct_finddata_t (time_t, _fsize_t);
                     ^
c:\mingw\include\io.h:335:21: error: 'time_t' does not name a type
 struct _wfinddata_t __struct_finddata_t (time_t, _fsize_t);
                     ^
c:\mingw\include\io.h:335:21: error: 'time_t' does not name a type
 struct _wfinddata_t __struct_finddata_t (time_t, _fsize_t);
                     ^
c:\mingw\include\io.h:336:24: error: 'time_t' does not name a type
 struct _wfinddatai64_t __struct_finddata_t (time_t, __int64);
                        ^
c:\mingw\include\io.h:336:24: error: 'time_t' does not name a type
 struct _wfinddatai64_t __struct_finddata_t (time_t, __int64);
                        ^
c:\mingw\include\io.h:336:24: error: 'time_t' does not name a type
 struct _wfinddatai64_t __struct_finddata_t (time_t, __int64);
                        ^
c:\mingw\include\io.h:362:24: error: '__time64_t' does not name a type
 struct __wfinddata64_t __struct_finddata_t (__time64_t, __int64);
                        ^
c:\mingw\include\io.h:362:24: error: '__time64_t' does not name a type
 struct __wfinddata64_t __struct_finddata_t (__time64_t, __int64);
                        ^
c:\mingw\include\io.h:362:24: error: '__time64_t' does not name a type
 struct __wfinddata64_t __struct_finddata_t (__time64_t, __int64);
                        ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\postypes.h:40:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:146:11: error: '::fwide' has not been declared
   using ::fwide;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:153:11: error: '::mbsinit' has not been declared
   using ::mbsinit;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:164:11: error: '::vfwscanf' has not been declared
   using ::vfwscanf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:170:11: error: '::vswscanf' has not been declared
   using ::vswscanf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:174:11: error: '::vwscanf' has not been declared
   using ::vwscanf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:191:11: error: '::wcstof' has not been declared
   using ::wcstof;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:198:11: error: '::wmemcmp' has not been declared
   using ::wmemcmp;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:199:11: error: '::wmemcpy' has not been declared
   using ::wmemcpy;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:200:11: error: '::wmemmove' has not been declared
   using ::wmemmove;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:201:11: error: '::wmemset' has not been declared
   using ::wmemset;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:208:11: error: '::wmemchr' has not been declared
   using ::wmemchr;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar: In function 'wchar_t* std::wmemchr(wchar_t*, wchar_t, std::size_t)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:229:61: error: invalid conversion from 'const wchar_t*' to 'wchar_t*' [-fpermissive]
   { return wmemchr(const_cast<const wchar_t*>(__p), __c, __n); }
                                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:228:3: note: initializing argument 1 of 'wchar_t* std::wmemchr(wchar_t*, wchar_t, std::size_t)'
   wmemchr(wchar_t* __p, wchar_t __c, size_t __n)
   ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar: At global scope:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:248:11: error: '::wcstold' has not been declared
   using ::wcstold;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:257:11: error: '::wcstoll' has not been declared
   using ::wcstoll;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:258:11: error: '::wcstoull' has not been declared
   using ::wcstoull;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:264:22: error: '__gnu_cxx::wcstold' has not been declared
   using ::__gnu_cxx::wcstold;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:265:22: error: '__gnu_cxx::wcstoll' has not been declared
   using ::__gnu_cxx::wcstoll;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:266:22: error: '__gnu_cxx::wcstoull' has not been declared
   using ::__gnu_cxx::wcstoull;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:280:14: error: 'std::wcstof' has not been declared
   using std::wcstof;
              ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:283:14: error: 'std::vfwscanf' has not been declared
   using std::vfwscanf;
              ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:286:14: error: 'std::vswscanf' has not been declared
   using std::vswscanf;
              ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:289:14: error: 'std::vwscanf' has not been declared
   using std::vwscanf;
              ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:293:14: error: 'std::wcstold' has not been declared
   using std::wcstold;
              ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:294:14: error: 'std::wcstoll' has not been declared
   using std::wcstoll;
              ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:295:14: error: 'std::wcstoull' has not been declared
   using std::wcstoull;
              ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:40:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h: In static member function 'static int std::char_traits<wchar_t>::compare(const char_type*, const char_type*, std::size_t)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:330:39: error: 'wmemcmp' was not declared in this scope
       { return wmemcmp(__s1, __s2, __n); }
                                       ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h: In static member function 'static const char_type* std::char_traits<wchar_t>::find(const char_type*, std::size_t, const char_type&)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:338:37: error: invalid conversion from 'const char_type* {aka const wchar_t*}' to 'wchar_t*' [-fpermissive]
       { return wmemchr(__s, __a, __n); }
                                     ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\postypes.h:40:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cwchar:228:3: note: initializing argument 1 of 'wchar_t* std::wmemchr(wchar_t*, wchar_t, std::size_t)'
   wmemchr(wchar_t* __p, wchar_t __c, size_t __n)
   ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:40:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h: In static member function 'static std::char_traits<wchar_t>::char_type* std::char_traits<wchar_t>::move(std::char_traits<wchar_t>::char_type*, const char_type*, std::size_t)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:342:40: error: 'wmemmove' was not declared in this scope
       { return wmemmove(__s1, __s2, __n); }
                                        ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h: In static member function 'static std::char_traits<wchar_t>::char_type* std::char_traits<wchar_t>::copy(std::char_traits<wchar_t>::char_type*, const char_type*, std::size_t)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:346:39: error: 'wmemcpy' was not declared in this scope
       { return wmemcpy(__s1, __s2, __n); }
                                       ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h: In static member function 'static std::char_traits<wchar_t>::char_type* std::char_traits<wchar_t>::assign(std::char_traits<wchar_t>::char_type*, std::size_t, std::char_traits<wchar_t>::char_type)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\char_traits.h:350:37: error: 'wmemset' was not declared in this scope
       { return wmemset(__s, __a, __n); }
                                     ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\ext\string_conversions.h:43:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2849,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:52,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio: At global scope:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:175:11: error: '::snprintf' has not been declared
   using ::snprintf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:176:11: error: '::vfscanf' has not been declared
   using ::vfscanf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:177:11: error: '::vscanf' has not been declared
   using ::vscanf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:178:11: error: '::vsnprintf' has not been declared
   using ::vsnprintf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:179:11: error: '::vsscanf' has not been declared
   using ::vsscanf;
           ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:185:22: error: '__gnu_cxx::snprintf' has not been declared
   using ::__gnu_cxx::snprintf;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:186:22: error: '__gnu_cxx::vfscanf' has not been declared
   using ::__gnu_cxx::vfscanf;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:187:22: error: '__gnu_cxx::vscanf' has not been declared
   using ::__gnu_cxx::vscanf;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:188:22: error: '__gnu_cxx::vsnprintf' has not been declared
   using ::__gnu_cxx::vsnprintf;
                      ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\cstdio:189:22: error: '__gnu_cxx::vsscanf' has not been declared
   using ::__gnu_cxx::vsscanf;
                      ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\string:52:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:40,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'long long int std::stoll(const string&, std::size_t*, int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2873:31: error: 'strtoll' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'long long unsigned int std::stoull(const string&, std::size_t*, int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2878:31: error: 'strtoull' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'float std::stof(const string&, std::size_t*)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2884:31: error: 'strtof' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'long double std::stold(const string&, std::size_t*)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2892:31: error: 'strtold' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2899:45: error: 'vsnprintf' is not a member of 'std'
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(int),
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(unsigned int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2904:45: error: 'vsnprintf' is not a member of 'std'
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(long int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2910:45: error: 'vsnprintf' is not a member of 'std'
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(long),
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(long unsigned int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2915:45: error: 'vsnprintf' is not a member of 'std'
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(long long int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2921:45: error: 'vsnprintf' is not a member of 'std'
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(long long unsigned int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2927:45: error: 'vsnprintf' is not a member of 'std'
   { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(float)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2936:45: error: 'vsnprintf' is not a member of 'std'
     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(double)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2945:45: error: 'vsnprintf' is not a member of 'std'
     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'std::string std::to_string(long double)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2954:45: error: 'vsnprintf' is not a member of 'std'
     return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n,
                                             ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'long long int std::stoll(const wstring&, std::size_t*, int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2976:31: error: 'wcstoll' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'long long unsigned int std::stoull(const wstring&, std::size_t*, int)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2981:31: error: 'wcstoull' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'float std::stof(const wstring&, std::size_t*)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2987:31: error: 'wcstof' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }
                               ^
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h: In function 'long double std::stold(const wstring&, std::size_t*)':
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\basic_string.h:2995:31: error: 'wcstold' is not a member of 'std'
   { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }
                               ^
tokumaru.cc: In function 'void CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&)':
tokumaru.cc:156:33: error: there are no arguments to 'omp_get_thread_num' that depend on a template parameter, so a declaration of 'omp_get_thread_num' must be available [-fpermissive]
         tn = omp_get_thread_num(); nt = omp_get_num_threads();
                                 ^
tokumaru.cc:156:33: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
tokumaru.cc:156:61: error: there are no arguments to 'omp_get_num_threads' that depend on a template parameter, so a declaration of 'omp_get_num_threads' must be available [-fpermissive]
         tn = omp_get_thread_num(); nt = omp_get_num_threads();
                                                             ^
tokumaru.cc: In instantiation of 'void CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]':
tokumaru.cc:236:65:   required from 'void CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]'
tokumaru.cc:419:96:   required from here
tokumaru.cc:156:33: error: 'omp_get_thread_num' was not declared in this scope
         tn = omp_get_thread_num(); nt = omp_get_num_threads();
                                 ^
tokumaru.cc:156:61: error: 'omp_get_num_threads' was not declared in this scope
         tn = omp_get_thread_num(); nt = omp_get_num_threads();
                                                             ^
tokumaru.cc:182:16: error: no matching function for call to 'CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record::Record(<brace-enclosed initializer list>)'
     targets[0] = Record{0, ~0u, false};
                ^
tokumaru.cc:182:16: note: candidates are:
tokumaru.cc:175:12: note: constexpr CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record::Record()
     struct Record { unsigned distance=~0u, previous=~0u; bool visited=false; };
            ^
tokumaru.cc:175:12: note:   candidate expects 0 arguments, 3 provided
tokumaru.cc:175:12: note: constexpr CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record::Record(const CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record&)
tokumaru.cc:175:12: note:   candidate expects 1 argument, 3 provided
tokumaru.cc:175:12: note: constexpr CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record::Record(CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record&&)
tokumaru.cc:175:12: note:   candidate expects 1 argument, 3 provided
tokumaru.cc: At global scope:
tokumaru.cc:69:13: error: 'void CompressWholeBlock(const unsigned char*, unsigned int, F&&, const unsigned char*) [with F = CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::<lambda(unsigned int, unsigned int)>]', declared using local type 'CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::<lambda(unsigned int, unsigned int)>', is used but never defined [-fpermissive]
 static void CompressWholeBlock(const unsigned char* tiles, unsigned numtiles, F&& PutBits,
             ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\queue:64:0,
                 from tokumaru.cc:34:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_queue.h:411:7: error: 'std::priority_queue<_Tp, _Sequence, _Compare>::priority_queue(const _Compare&, _Sequence&&) [with _Tp = std::pair<unsigned int, unsigned int>; _Sequence = std::vector<std::pair<unsigned int, unsigned int> >; _Compare = CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Prioritize]', declared using local type 'const CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Prioritize', is used but never defined [-fpermissive]
       priority_queue(const _Compare& __x = _Compare(),
       ^
In file included from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\vector:64:0,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\random.h:34,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\random:49,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_algo.h:66,
                 from c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\algorithm:62,
                 from tokumaru.cc:30:
c:\mingw\lib\gcc\mingw32\4.9.3\include\c++\bits\stl_vector.h:779:7: error: 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) [with _Tp = CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record; _Alloc = std::allocator<CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record>; std::vector<_Tp, _Alloc>::reference = CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record&; std::vector<_Tp, _Alloc>::size_type = unsigned int]', declared using local type '__gnu_cxx::__alloc_traits<std::allocator<CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record> >::value_type {aka CompressTilesWithBlockSplitting(const unsigned char*, unsigned int, F&&) [with F = CompressTiles(const unsigned char*, unsigned int, F&&) [with F = main(int, char**)::<lambda(unsigned char)>]::<lambda(unsigned int, unsigned int)>&]::Record}', is used but never defined [-fpermissive]
       operator[](size_type __n) _GLIBCXX_NOEXCEPT
       ^
make: *** [tokumaru] Error 1

Incidentally, the error log is 2 times longer than the code to be cmpiled. :(
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Tile encoder/decoder

Post by thefox »

Looks like something is seriously wrong with your compiler setup. It shouldn't barf on #include <algorithm> whether the source needs C++14 or not.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Post Reply