-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathdoc.go
More file actions
587 lines (584 loc) · 31.5 KB
/
Copy pathdoc.go
File metadata and controls
587 lines (584 loc) · 31.5 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
package png2prg
import (
"flag"
"fmt"
)
func PrintUsage() {
fmt.Println("usage: ./png2prg [-help -h -d -q -v -bpc 0,6,14,3 -o outfile.prg -td testdata] FILE [FILE..]")
}
func PrintHelp() {
fmt.Printf("# PNG2PRG %v by burg\n", Version)
fmt.Println()
fmt.Println("Png2prg converts a 320x200 image (png/gif/jpeg) to a c64 hires or")
fmt.Println("multicolor bitmap, charset, petscii, ecm or sprites prg. It will find the best")
fmt.Println("matching palette and background/bitpair-colors automatically, no need to modify")
fmt.Println("your source images or configure a palette.")
fmt.Println()
fmt.Println("Vice screenshots with default borders (384x272) are automatically cropped.")
fmt.Println("Vice's main screen offset is at x=32, y=35.")
fmt.Println("Quite a few people (and possibly tools too) use the incorrect 32,36 offset.")
fmt.Println("Use the -alt-offset or -ao flag to use 32,36 as offset.")
fmt.Println("Images in sprite dimensions will be converted to sprites.")
fmt.Println()
fmt.Println("The resulting .prg includes the 2-byte start address and optional displayer.")
fmt.Println("The displayers can optionally play a .sid tune.")
fmt.Println()
fmt.Println("This tool can be used in all buildchains on all common platforms.")
fmt.Println()
fmt.Println("## What Is New")
fmt.Println()
fmt.Println("Png2prg 1.12 introduces animation.csv support for custom delays per frame.")
fmt.Println("See 'Animation csv' below for details.")
fmt.Println("The -no-loop flag causes animations to only display once.")
fmt.Println()
fmt.Println("This release contains an important bugfix related to mixedcharsets,")
fmt.Println("where in some cases, png2prg would require more unique chars than necessary.")
fmt.Println("There were more issues with png2prg 1.10, which were hotfixed in 1.10.1.")
fmt.Println("It is best to delete any 1.10 version and upgrade to 1.12.")
fmt.Println()
fmt.Println("ECM conversion has been improved, now png2prg also searches for potential")
fmt.Println("char reduction by searching for invertable characters.")
fmt.Println()
fmt.Println("Trident added [devcontainer files](https://github.com/staD020/png2prg/commit/6cb6c48a2804fa5210cf704e0af4cff3313398fe) for setting up a Docker")
fmt.Println("development environment to compile png2prg directly from within VSCode.")
fmt.Println()
fmt.Println("See 'Changes for version 1.12' below for more features and details.")
fmt.Println()
fmt.Println("## What it is *not*")
fmt.Println()
fmt.Println("Png2prg is not a tool to wire fullcolor images. It needs input images to")
fmt.Println("already be compliant with c64 color and size restrictions.")
fmt.Println("In verbose mode (-v) it outputs locations of color clashes, if any.")
fmt.Println()
fmt.Println("If you do need to wire fullcolor images, check out Youth's [Retropixels](https://www.micheldebree.nl/retropixels/).")
fmt.Println()
fmt.Println("## Supported Graphics Modes")
fmt.Println()
fmt.Println(" koala: multicolor bitmap (max 4 colors per char)")
fmt.Println(" hires: singlecolor bitmap (max 2 colors per char)")
fmt.Println(" mixedcharset: multicolor charset (max 4 colors per char (fixed bgcol, d022, d023))")
fmt.Println(" mccharset: multicolor charset (max 4 colors)")
fmt.Println(" sccharset: singlecolor charset (max 2 colors per char (fixed bgcol))")
fmt.Println(" petscii: singlecolor rom charset (max 2 colors per char (fixed bgcol))")
fmt.Println(" ecm: singlecolor charset (max 2 colors per char (4 fixed bgcolors), max 64 chars)")
fmt.Println(" mcsprites: multicolor sprites (max 4 colors)")
fmt.Println(" scsprites: singlecolor sprites (max 2 colors)")
fmt.Println(" mcibitmap: 320x200 multicolor interlace bitmap (max 4 colors per char/frame)")
fmt.Println()
fmt.Println("Png2prg is mostly able to autodetect the correct graphics mode, but you can")
fmt.Println("also force a specific graphics mode with the -mode flag:")
fmt.Println()
fmt.Println(" ./png2prg -m koala image.png")
fmt.Println()
fmt.Println("## Koala or Hires Bitmap")
fmt.Println()
fmt.Println(" Bitmap: $2000 - $3f3f")
fmt.Println(" Screen: $3f40 - $4327")
fmt.Println(" D020: $4328 (singlecolor only)")
fmt.Println(" D800: $4328 - $470f (multicolor only)")
fmt.Println(" D021: $4710 (multicolor only, low-nibble)")
fmt.Println(" D020: $4710 (multicolor only, high-nibble)")
fmt.Println()
fmt.Println("## Multicolor Interlace Bitmap")
fmt.Println()
fmt.Println("You can supply one 320x200 multicolor image with max 4 colors per 8x8 pixel")
fmt.Println("char per frame of which at least 2 are shared (the D021 and D800 colors).")
fmt.Println()
fmt.Println("Or supply both frames in regular koala specs (-interlace flag required).")
fmt.Println("When making screenshots in vice, please disable the d016 pixel shift manually.")
fmt.Println()
fmt.Println(" ./png2prg -i testdata/madonna/frame_0.png testdata/madonna/frame_1.png")
fmt.Println()
fmt.Println("### Drazlace (shared screenram and colorram for both frames)")
fmt.Println()
fmt.Println(" ./png2prg testdata/madonna/cjam_pure_madonna.png")
fmt.Println()
fmt.Println(" D800: $5800 - $5be7")
fmt.Println(" Screen: $5c00 - $5fe7")
fmt.Println(" Bitmap1: $6000 - $7f3f")
fmt.Println(" D021: $7f40 (low-nibble)")
fmt.Println(" D020: $7f40 (high-nibble)")
fmt.Println(" D016Offset: $7f42")
fmt.Println(" Bitmap2: $8000 - $9f3f")
fmt.Println()
fmt.Println("### Multicolor Interlace (shared colorram, true paint .mci format)")
fmt.Println()
fmt.Println(" ./png2prg -i -d016 1 testdata/mcinterlace/parriot?.png")
fmt.Println()
fmt.Println(" Screen1: $9c00 - $9fe7")
fmt.Println(" D021: $9fe8 (low-nibble)")
fmt.Println(" D020: $9fe8 (high-nibble)")
fmt.Println(" D016Offset: $9fe9")
fmt.Println(" Bitmap1: $a000 - $bf3f")
fmt.Println(" Bitmap2: $c000 - $df3f")
fmt.Println(" Screen2: $e000 - $e3e7")
fmt.Println(" D800: $e400 - $e7e7")
fmt.Println()
fmt.Println("## Singlecolor, PETSCII or ECM Charset (individual d800 colors)")
fmt.Println()
fmt.Println("By default charsets are packed, they only contain unique characters.")
fmt.Println("If you do not want charpacking, eg for a 1x1 charset, please use -no-pack.")
fmt.Println()
fmt.Println("With ECM -bitpair-colors can be used to force d021-d024 colors.")
fmt.Println()
fmt.Println("NB: individual d800 colors are not supported with -no-pack.")
fmt.Println()
fmt.Println(" ./png2prg -m sccharset testdata/hirescharset/ohno_logo.png")
fmt.Println(" ./png2prg -m petscii testdata/petscii/hein_hibiscus.png")
fmt.Println(" ./png2prg -m ecm testdata/ecm/xpardey.png")
fmt.Println(" ./png2prg -m ecm testdata/ecm/shampoo.png")
fmt.Println(" ./png2prg -m ecm -bpc 2,7,14,0 testdata/ecm/orion.png")
fmt.Println()
fmt.Println(" Charset: $2000-$27ff (omitted for petscii)")
fmt.Println(" Screen: $2800-$2be7")
fmt.Println(" D800: $2c00-$2fe7")
fmt.Println(" D020: $2fe8")
fmt.Println(" D021: $2fe9")
fmt.Println(" D022: $2fea (ecm only)")
fmt.Println(" D023: $2feb (ecm only)")
fmt.Println(" D024: $2fec (ecm only)")
fmt.Println()
fmt.Println("## Mixed Multi/Singlecolor Charset (individual d800 colors)")
fmt.Println()
fmt.Println("Png2prg tries to figure out the right -bitpair-colors and auto-corrects")
fmt.Println("where it can, but there still are edge-cases like the ones below.")
fmt.Println("If an impossible color is found, an error will be displayed.")
fmt.Println("Swap some -bpc colors around and retry.")
fmt.Println("There can also be cases where manual -bpc colors can influence char-count or")
fmt.Println("packed size.")
fmt.Println()
fmt.Println("You may want to add the -brute-force flag so most color options will be tried.")
fmt.Println("The best packed result wins, not necessarily the version with the least amount")
fmt.Println("of chars.")
fmt.Println()
fmt.Println(" ./png2prg -m mixedcharset testdata/mixedcharset/hein_neo.png")
fmt.Println(" ./png2prg -m mixedcharset testdata/mixedcharset/huntress.gif")
fmt.Println(" ./png2prg -m mixedcharset -bpc 3 testdata/mixedcharset/shine.png")
fmt.Println(" ./png2prg -m mixedcharset -bpc 0 testdata/mixedcharset/charsetcompo.png")
fmt.Println()
fmt.Println(" Charset: $2000-$27ff")
fmt.Println(" Screen: $2800-$2be7")
fmt.Println(" D800: $2c00-$2fe7")
fmt.Println(" D020: $2fe8")
fmt.Println(" D021: $2fe9")
fmt.Println(" D022: $2fea")
fmt.Println(" D023: $2feb")
fmt.Println()
fmt.Println("## Single or Multicolor Sprites")
fmt.Println()
fmt.Println("If the source image size is a multiple of a 24x21 pixel sprite,")
fmt.Println("the image is considered to contain sprites.")
fmt.Println()
fmt.Println("The image will be converted from left to right, top to bottom.")
fmt.Println()
fmt.Println(" ./png2prg image.png")
fmt.Println(" ./png2prg -m scsprites image.png")
fmt.Println(" ./png2prg -m mcsprites image.png")
fmt.Println()
fmt.Println(" Sprite 1: $2000-$203f")
fmt.Println(" Sprite 2: $2040-$207f")
fmt.Println(" ...")
fmt.Println()
fmt.Println("## Bitpair Colors")
fmt.Println()
fmt.Println("By default, png2prg guesses bitpair colors by itself. In most cases you")
fmt.Println("don't need to configure anything. It will provide a mostly normalized image")
fmt.Println("which should yield good pack results, but your miles may vary.")
fmt.Println()
fmt.Println("To give you more control, you can force/prefer a specific bitpair")
fmt.Println("color-order. Use c64 colors, so 0 for black, 1 for white, 2 for red, etc.")
fmt.Println()
fmt.Println("The following example will force background color 0 for bitpair 00 and")
fmt.Println("prefer colors 6,14,3 for bitpairs 01,10,11:")
fmt.Println()
fmt.Println(" ./png2prg -bitpair-colors 0,6,14,3 image.png")
fmt.Println()
fmt.Println("It's also possible to explicitly skip certain bitpair preferences with -1:")
fmt.Println()
fmt.Println(" ./png2prg -bitpair-colors 0,-1,-1,3 image.png")
fmt.Println()
fmt.Println("## Animations")
fmt.Println()
fmt.Println("When multiple files are added, they are treated as animation frames.")
fmt.Println("You can also supply an animated .gif.")
fmt.Println()
fmt.Println("## Sprite Animation")
fmt.Println()
fmt.Println("Each frame will be concatenated in the output .prg.")
fmt.Println()
fmt.Println("## Bitmap Animation (only koala and hires)")
fmt.Println()
fmt.Println("Note that png2prg uses a rather simple generic diff approach, where small")
fmt.Println("changes frame by frame work well. Trying to change large areas at once")
fmt.Println("is not advised.")
fmt.Println("Use the -no-fade flag if you run out of memory.")
fmt.Println()
fmt.Println("The first image will be exported with all framedata appended.")
fmt.Println("Koala animation frames start at $4711, hires at $4329.")
fmt.Println()
fmt.Println("The frame files are following this format.")
fmt.Println("Each frame consists of 1 or more chunks. A chunk looks like this:")
fmt.Println()
fmt.Println(" .byte $03 // number of chars in this chunk")
fmt.Println(" // $00 marks end of frame")
fmt.Println(" // $ff marks end of all frames")
fmt.Println(" .word bitmap // bitmap address of this chunk (the high byte is <$20)")
fmt.Println(" .word screen // screenram address (the high byte is <$04)")
fmt.Println()
fmt.Println(" For each char in this chunk:")
fmt.Println()
fmt.Println(" .byte 0,31,15,7,8,34,0,128 // pixels")
fmt.Println(" .byte $64 // screenram colors")
fmt.Println(" .byte $01 // colorram color (koala only)")
fmt.Println(" ... // next char(s)")
fmt.Println()
fmt.Println(" ... // next chunks")
fmt.Println(" .byte 0 // end of frame")
fmt.Println(" .byte 6 // wait for 6 frames")
fmt.Println(" ... // next frame(s)")
fmt.Println(" .byte $ff // end of all frames")
fmt.Println()
fmt.Println("## PETSCII and Charset Animation")
fmt.Println()
fmt.Println("Only petscii and sccharset modes support different background and")
fmt.Println("bordercolors per frame.")
fmt.Println("All chars used in all frames must fit into a single 256 char charset.")
fmt.Println()
fmt.Println("Each frame consists of 1 or more chunks. A chunk looks like this:")
fmt.Println()
fmt.Println(" .byte $xy // $y = bgcol, $x = bordercol (only for petscii/sccharset)")
fmt.Println(" .byte $03 // number of chars in this chunk")
fmt.Println(" // $00 marks end of frame")
fmt.Println(" // $ff marks end of all frames")
fmt.Println(" .word screen // screenram address (the high byte is <$04)")
fmt.Println()
fmt.Println(" For each char in this chunk:")
fmt.Println()
fmt.Println(" .byte $03 // character")
fmt.Println(" .byte $01 // colorram color")
fmt.Println(" ... // next char(s)")
fmt.Println()
fmt.Println(" ... // next chunks")
fmt.Println(" .byte 0 // end of frame")
fmt.Println(" .byte 6 // wait for 6 frames")
fmt.Println(" ... // next frame(s)")
fmt.Println(" .byte $ff // end of all frames")
fmt.Println()
fmt.Println("## Animation csv")
fmt.Println()
fmt.Println("Since version 1.12 animation.csv support has been added to give more")
fmt.Println("freedom to users wanting to create animation displayers.")
fmt.Println("It is now possible to use a custom frame-delay per frame.")
fmt.Println()
fmt.Println("The csv should contain rows of frame delay value and image, where the")
fmt.Println("delay can be any value from 0 till 255. The highest delay is a little")
fmt.Println("over 5 seconds on PAL systems.")
fmt.Println("If you want longer delays, just copy a row.")
fmt.Println()
fmt.Println(" 10,frame0.png")
fmt.Println(" 50,frame1.png")
fmt.Println(" 10,frame2.png")
fmt.Println()
fmt.Println("Examples can be found here: [Évoluer by The Sarge](https://github.com/staD020/png2prg/blob/master/testdata/evoluer/evoluer.csv) and [Rose by Sander](https://github.com/staD020/png2prg/blob/master/testdata/petscii/anim/rose.csv)")
fmt.Println()
fmt.Println(" png2prg -d -o evoluer.prg -sid testdata/evoluer/Evoluer.sid testdata/evoluer/evoluer.csv")
fmt.Println(" png2prg -d -o rose.prg testdata/petscii/anim/rose.csv")
fmt.Println()
fmt.Println("## Displayer")
fmt.Println()
fmt.Println("The -d or -display flag will link displayer code infront of the picture.")
fmt.Println("By default it will also crunch the resulting file with Antonio Savona's")
fmt.Println("[TSCrunch](https://github.com/tonysavon/TSCrunch/) with a couple of changes in my own [fork](https://github.com/staD020/TSCrunch/).")
fmt.Println()
fmt.Println("All displayers except for sprites support adding a .sid.")
fmt.Println("Multispeed sids are supported as long as the .sid initializes the CIA timers")
fmt.Println("correctly.")
fmt.Println()
fmt.Println("You can use sids located from $0e00-$1fff or $e000+ in the displayers.")
fmt.Println("More areas may be free depending on graphics type.")
fmt.Println("A memory usage map is shown on error and in -vv (very verbose) mode.")
fmt.Println()
fmt.Println("If needed, you can relocate most sids using lft's [sidreloc](http://www.linusakesson.net/software/sidreloc/index.php).")
fmt.Println()
fmt.Println("Zeropages $08-$0f are used in the animation displayers, while none are used")
fmt.Println("in hires/koala displayers, increasing sid compatibility.")
fmt.Println()
fmt.Println("## Brute Force Mode and Pack Optimization")
fmt.Println()
fmt.Println("By default png2prg 1.8 does a pretty good job at optimizing the resulting prg")
fmt.Println("for crunchers and packers. It is not enough to beat [SPOT 1.3](https://csdb.dk/release/?id=242492).")
fmt.Println()
fmt.Println("The optimization techniques used by png2prg are also responsible for cleaning")
fmt.Println("up the bitmap, making it ideal for animations and color effects.")
fmt.Println()
fmt.Println("### -brute-force (-bf)")
fmt.Println()
fmt.Println("Iterates are over many -bitpair-colors permutations automatically, packs")
fmt.Println("with the built in TSCrunch and selects the shortest.")
fmt.Println()
fmt.Println(" ./png2prg -bf image.png")
fmt.Println()
fmt.Println("The -brute-force mode can be used in combination with additional flags.")
fmt.Println()
fmt.Println("### -no-bitpair-counters (-nbc)")
fmt.Println()
fmt.Println("Disable counting of bitpairs per color to guess a bitpair for a color.")
fmt.Println()
fmt.Println(" ./png2prg -bf -nbc image.png")
fmt.Println()
fmt.Println("### -no-prev-char-colors (-npcc)")
fmt.Println()
fmt.Println("Disable lookback to previous char's charcolors to guess a bitpair for a color.")
fmt.Println()
fmt.Println(" ./png2prg -bf -npcc image.png")
fmt.Println()
fmt.Println("Since TSCrunch is optimized for speed, packing with Dali can give varying")
fmt.Println("results. This is also the reason for not including these options in the")
fmt.Println("brute force permutations automatically.")
fmt.Println()
fmt.Println("## Benchmark")
fmt.Println()
fmt.Println("The [koala otpimizing thread](https://csdb.dk/forums/?roomid=13&topicid=38311&showallposts=1) on csdb has gained some interest in the scene.")
fmt.Println("Since Sparta released [SPOT](https://csdb.dk/release/?id=242492) it has been the best optimizer available.")
fmt.Println()
fmt.Println("Png2prg 1.8 has improved optimization techniques but requires -brute-force")
fmt.Println("mode to beat SPOT 1.3. Manual flags can optimize even better in some cases.")
fmt.Println()
fmt.Println("All koalas are packed with [Dali 0.3.2](https://csdb.dk/release/?id=223584).")
fmt.Println()
fmt.Println(" +---------+--------+----------+------------+--------+")
fmt.Println(" | spot1.3 | p2p1.8 | p2p1.8bf | p2p1.8best | p2p1.6 |")
fmt.Println(" +---------+--------+----------+------------+--------+")
fmt.Println(" | 7332 | 7372 | 7332 | 7324 | 7546 | Untitled/Floris")
fmt.Println(" | 5136 | 5190 | 5149 | bf | 5464 | Song of the Sunset/Mermaid")
fmt.Println(" | 5968 | 5998 | 5963 | bf | 6155 | Short Circuit/Karen Davies")
fmt.Println(" | 3618 | 3647 | 3616 | 3589 | 3830 | Portrait L+D/Sander")
fmt.Println(" | 5094 | 5080 | 5083 | 5078 | 5320 | Weee/Mermaid")
fmt.Println(" | 7497 | 7471 | 7458 | bf | 7612 | Deadlock/Robin Levy")
fmt.Println(" | 8068 | 8097 | 8046 | 8038 | 8227 | Room with a view/Veto")
fmt.Println(" | 7445 | 7490 | 7432 | bf | 7582 | Vangelis/Talent")
fmt.Println(" | 6759 | 6739 | 6737 | bf | 6963 | Temple of Tears/Hend")
fmt.Println(" | 7859 | 7848 | 7839 | 7821 | 7998 | Thanos/JonEgg")
fmt.Println(" | 4859 | 4849 | 4782 | bf | 4983 | Solar-Sonar/Leon")
fmt.Println(" | 5640 | 5671 | 5613 | bf | 5869 | Cisco Heat/Alan Grier")
fmt.Println(" | 6243 | 6286 | 6228 | bf | 6430 | Daylight/Sulevi")
fmt.Println(" | 2850 | 2884 | 2848 | bf | 3092 | Yie Ar Kung Fu/Steve Wahid")
fmt.Println(" | 6727 | 6721 | 6730 | 6711 | 6901 | Lee/The Sarge")
fmt.Println(" | 7837 | 7828 | 7798 | bf | 7960 | Parrot/Mirage")
fmt.Println(" | 4559 | 4536 | 4494 | bf | 4821 | Dragon's Lair")
fmt.Println(" | 4275 | 4324 | 4292 | 4284 | 4519 | Scorpion/SIR'88")
fmt.Println(" | 5562 | 5558 | 5506 | bf | 5668 | Hatching/Joe")
fmt.Println(" +---------+--------+----------+------------+--------+")
fmt.Println(" | 113328 | 113589 | 112946 | 112853 | 116940 | Total")
fmt.Println(" +---------+--------+----------+------------+--------+")
fmt.Println()
fmt.Println(" - p2p1.8: default png2prg result w/o options")
fmt.Println(" - p2p1.8bf: -brute-force mode")
fmt.Println(" - p2p1.8best: hand-picked -bitpair-colors, or bruteforced with -npcc and/or -nbc flags")
fmt.Println(" - p2p1.6: default png2prg 1.6 result w/o options")
fmt.Println()
fmt.Println("## Examples")
fmt.Println()
fmt.Println("This release contains examples with all assets included for you to test with.")
fmt.Println("Also included are the assets of [Évoluer](https://csdb.dk/release/?id=220170) by The Sarge and Flotsam.")
fmt.Println("A larger set of testdata can be found in the [github repo](https://github.com/staD020/png2prg/tree/master/testdata).")
fmt.Println()
fmt.Println("## Install from source")
fmt.Println()
fmt.Println("Png2prg was built on Linux, building on Mac should work out of the box.")
fmt.Println("For Windows, try out Windows Subsystem Linux (WSL), works pretty well.")
fmt.Println("However, natively building on Windows should be easy enough, look at")
fmt.Println("Compiling without Make below.")
fmt.Println()
fmt.Println("The compiled displayer prgs are included in the repo to ease building")
fmt.Println("and importing png2prg as a library. Java is only required to build")
fmt.Println("the displayers with KickAssembler (included in the repo).")
fmt.Println()
fmt.Println("But first [install Go 1.20 or higher](https://go.dev/dl/).")
fmt.Println()
fmt.Println("### Simple install")
fmt.Println()
fmt.Println(" go install -v github.com/staD020/png2prg@master")
fmt.Println()
fmt.Println("### Compiling with Make (recommended)")
fmt.Println()
fmt.Println(" git clone https://github.com/staD020/png2prg.git")
fmt.Println(" cd png2prg")
fmt.Println(" make -j")
fmt.Println()
fmt.Println("Build for all common targets:")
fmt.Println()
fmt.Println(" make all -j")
fmt.Println()
fmt.Println("### Compiling without Make")
fmt.Println()
fmt.Println(" go build ./cmd/png2prg")
fmt.Println()
fmt.Println("## Install and use as library")
fmt.Println()
fmt.Println("In your Go project's path, go get the library:")
fmt.Println()
fmt.Println(" go get github.com/staD020/png2prg")
fmt.Println()
fmt.Println("In essence png2prg implements the [io.WriterTo](https://pkg.go.dev/io#WriterTo) interface.")
fmt.Println("Typical usage could look like below. A more complex example can be found")
fmt.Println("in the [source](https://github.com/staD020/png2prg/blob/master/cmd/png2prg/main.go) of the cli tool.")
fmt.Println()
fmt.Println("```go")
fmt.Println("import (")
fmt.Println(" \"fmt\"")
fmt.Println(" \"io\"")
fmt.Println(" \"github.com/staD020/png2prg\"")
fmt.Println(")")
fmt.Println()
fmt.Println("func convertPNG(w io.Writer, png io.Reader) (int64, error) {")
fmt.Println(" p, err := png2prg.New(png2prg.Options{}, png)")
fmt.Println(" if err != nil {")
fmt.Println(" return 0, fmt.Errorf(\"png2prg.New failed: %w\", err)")
fmt.Println(" }")
fmt.Println(" return p.WriteTo(w)")
fmt.Println("}")
fmt.Println("```")
fmt.Println()
fmt.Printf("## Changes for version %s\n", Version)
fmt.Println()
fmt.Println(" - Bugfix: Fix regression with handling mixedcharsets that was increasing")
fmt.Println(" char usage count in some cases (thanks Shine).")
fmt.Println(" - Feature: Press CBM key in petscii (animation) displayers to switch")
fmt.Println(" charset case.")
fmt.Println(" - Feature: Add -brute-force support to all charset modes.")
fmt.Println(" - Feature: Improve ECM handling by searching for invertable characters to")
fmt.Println(" reduce char usage.")
fmt.Println(" - Feature: Add animation.csv support to allow for custom delays per frame.")
fmt.Println(" - Feature: Add -no-loop support for animations (thanks jab).")
fmt.Println(" - Feature: Add -no-fade support to other displayers (thanks Shine).")
fmt.Println(" - Feature: Disable repeating color optimization for koala & hires anims.")
fmt.Println(" This reduces animation size & runtime processing at the cost of initial")
fmt.Println(" image optimization.")
fmt.Println(" - Feature: Allow sids to use all memory below $0400 (thanks kbs).")
fmt.Println(" - Feature: VSCode Docker build support for a devcontainer was added by")
fmt.Println(" Trident (thanks!).")
fmt.Println(" - Experimental: Add secondary+tertiary preferred bitpair colors with -bpc2")
fmt.Println(" and -bpc3 (thanks Fungus).")
fmt.Println()
fmt.Println("## Changes for version 1.10.1")
fmt.Println()
fmt.Println(" - Play NTSC .sid tunes at the right speed (thanks Acrouzet).")
fmt.Println(" - Bugfix: palette detection must detect all hires colors, also on odd pixels.")
fmt.Println(" - Bugfix: dont look at border area to determine hires pixels.")
fmt.Println(" - Bugfix: fix -frame-delay for charset anim displayers.")
fmt.Println()
fmt.Println("## Changes for version 1.10")
fmt.Println()
fmt.Println(" - Add gfxmode to .sym files and display in terminal output (thanks Spider-J).")
fmt.Println(" - Add petscii animation support.")
fmt.Println(" - Add background and bordercolor to each petscii or sccharset animation frame.")
fmt.Println(" - Add -no-anim flag disable sc/mccharset animations and store frames as separate")
fmt.Println(" screens.")
fmt.Println(" - Add -no-fade flag for koala, hires, petscii and sccharset animation")
fmt.Println(" displayers, this frees up a lot of RAM for animation data and sid.")
fmt.Println(" - Code refactor, standardizing color and bitpair code, separated palettes in")
fmt.Println(" palettes.yaml and more.")
fmt.Println(" - Bugfix: repair -force-border-color.")
fmt.Println(" - Bugfix: handle blank ECM images as well as ECM images using few bg colors")
fmt.Println(" (thanks Brush).")
fmt.Println(" - Typofix: fix simple install docs (thanks IcePic).")
fmt.Println(" - Added another weird palette (thanks Fungus).")
fmt.Println()
fmt.Println("## Changes for version 1.8")
fmt.Println()
fmt.Println(" - Improve crunchiness by re-using the previous char's bitpair-colors.")
fmt.Println(" - Add -no-prev-char-colors flag to disable re-use of the previous char's")
fmt.Println(" bitpair-colors, in some cases this optimization causes worse pack results.")
fmt.Println(" - Add -brute-force mode to find bitpair color combinations with better")
fmt.Println(" crunchiness. Burns some CPU for a couple seconds.")
fmt.Println(" - Add -no-bitpair-counters flag to disable using bitpair counters per color")
fmt.Println(" for color guessing.")
fmt.Println(" - Added multi-frame support for mccharset, where all frames use the same")
fmt.Println(" charset.")
fmt.Println(" - Add support for any centered fullscreen image resolution bigger than")
fmt.Println(" 320x200 and other than 384x272.")
fmt.Println(" - Add support for Marq's PETSCII tool .png resolution 352x232 (thanks jab).")
fmt.Println(" - Bugfix: docs fixes related to installation from source (thanks jab).")
fmt.Println(" - Bugfix: hide findECMColors log behind -verbose mode (thanks jab).")
fmt.Println(" - Docs fix: add a bit more info for sprites (thanks fungus).")
fmt.Println()
fmt.Println("## Changes for version 1.6")
fmt.Println()
fmt.Println(" - Added -mode mixedcharset for mixed multicolor/singlecolor and")
fmt.Println(" individual d800 colors per char.")
fmt.Println(" - Modified -mode sccharset to use individual d800 colors per char.")
fmt.Println(" - Added -mode petscii.")
fmt.Println(" - Added -mode ecm.")
fmt.Println(" - Added -no-pack-empty to skip packing empty chars to filled chars to re-use")
fmt.Println(" for different colors. Only for mixed and ecm charsets.")
fmt.Println(" - Added -force-pack-empty for singlecolor and multicolor charset, may save")
fmt.Println(" a char, but usually pack-ratio is worse due to increased d800 color usage.")
fmt.Println(" - Improved auto-detection of graphics modes, including various charset modes.")
fmt.Println(" - Added sid support to charset displayers.")
fmt.Println(" - Added fullscreen fade in/out to charset displayers.")
fmt.Println(" - Bug Fix: -force-border-color for singlecolor charset (thanks Raistlin).")
fmt.Println(" - Bug Fix: do not write empty .prg file on error.")
fmt.Println(" - Standardized d02x colors in output.prg for charset modes.")
fmt.Println()
fmt.Println("## Changes for version 1.4")
fmt.Println()
fmt.Println(" - Support for even more far-out palette ranges (thanks Perplex).")
fmt.Println(" - Now throws an error if the palette can't be detected properly, this should")
fmt.Println(" never happen. Please let me know if you run into this error.")
fmt.Println(" - Separated library and cli tool.")
fmt.Println(" - Library supports the standard [io.Reader](https://pkg.go.dev/io#Reader) and [io.Writer](https://pkg.go.dev/io#Writer) interfaces.")
fmt.Println(" - Patched [TSCrunch](https://github.com/staD020/TSCrunch/) further to increase crunch speed and use less memory.")
fmt.Println(" - Added -parallel and -worker flags to treat each input file as standalone")
fmt.Println(" and convert all files in parallel. Gifs with multiple frames are still")
fmt.Println(" treated as animations.")
fmt.Println(" - Stop relying on .gif filename extension, detect it.")
fmt.Println(" - Add -alt-offset flag to force screenshot offset 32, 36), used by a few")
fmt.Println(" graphicians. Though, please switch to the correct 32, 35.")
fmt.Println(" - Add -symbols flag to write symbols to a .sym file.")
fmt.Println(" - Interlace support for mcibitmap (drazlace and truepaint).")
fmt.Println(" - Bugfix: allow blank images input (thanks Spider-J).")
fmt.Println(" - Allow colors not present in the image as -bitpair-colors (thanks Map).")
fmt.Println()
fmt.Println("## Changes for version 1.2")
fmt.Println()
fmt.Println(" - Added displayer for koala animations.")
fmt.Println(" - Added displayer for hires animations.")
fmt.Println(" - Added -frame-delay flag for animation displayers.")
fmt.Println(" - Added -wait-seconds flag for animation displayers.")
fmt.Println(" - Fixed bug in koala/hires displayers not allowing sids to overlap $c000-$c7ff.")
fmt.Println(" - Expanding wildcards: using pic??.png or pic*.png now also works on Windows.")
fmt.Println(" - Set bank via $dd00 in displayers.")
fmt.Println()
fmt.Println("## Changes for version 1.0")
fmt.Println()
fmt.Println(" - Added fullscreen fade in/out to koala and hires displayers.")
fmt.Println(" - Added optional .sid support for koala and hires displayers.")
fmt.Println(" - Added optional crunching for all displayers using TSCrunch.")
fmt.Println()
fmt.Println("## Credits")
fmt.Println()
fmt.Println("Png2prg was created by Burglar, using the following third-party libraries:")
fmt.Println()
fmt.Println("[TSCrunch 1.3](https://github.com/tonysavon/TSCrunch/) by Antonio Savona for optional crunching when exporting")
fmt.Println("an image with a displayer.")
fmt.Println()
fmt.Println("[Colfade Doc](https://csdb.dk/release/?id=132276) by Veto for the color fade tables used in the displayers.")
fmt.Println()
fmt.Println("[Kick Assembler](http://www.theweb.dk/KickAssembler/) by Slammer to compile the displayers.")
fmt.Println()
fmt.Println("[Go](https://go.dev/) by The Go Authors is the programming language used to create png2prg.")
fmt.Println()
fmt.Println("### Thanks to")
fmt.Println()
fmt.Println("Apollyon, Spider-J, Brush, The Sarge, Fungus, Jab, Shine, Raistlin, Perplex,")
fmt.Println("Map, Youth, IcePic, Sander, Guinea Pig, Krill, Christopher Jam, Sparta,")
fmt.Println("Acrouzet, Trident, Worrior1 and Antonio Savona.")
fmt.Println()
fmt.Println("## Options")
fmt.Println()
fmt.Println("```")
flag.PrintDefaults()
fmt.Println("```")
fmt.Println()
}