├── .gitignore ├── Examples ├── dumps │ ├── 00001_00001.txt │ ├── 00001_00002.txt │ ├── 00002_00001.txt │ ├── 00002_00002.txt │ ├── 00002_00003.txt │ ├── 00003_00001.txt │ ├── 00003_00002.txt │ ├── 00003_00003.txt │ ├── 00003_00004.txt │ ├── 00003_00005.txt │ ├── 00004_00001.txt │ ├── 00004_00002.txt │ ├── 00004_00003.txt │ ├── 00004_00004.txt │ ├── 00004_00005.txt │ ├── 00004_00006.txt │ ├── 00004_00007.txt │ ├── 00004_00008.txt │ ├── 00004_00009.txt │ ├── 00004_00010.txt │ ├── 00004_00011.txt │ ├── 00004_00012.txt │ ├── 00004_00013.txt │ ├── 00004_00014.txt │ ├── 00004_00015.txt │ ├── 00004_00016.txt │ ├── 00004_00017.txt │ ├── 00004_00018.txt │ ├── 00004_00019.txt │ ├── 00004_00020.txt │ ├── 00004_00021.txt │ ├── 00004_00022.txt │ ├── 00004_00023.txt │ ├── 00004_00024.txt │ ├── 00004_00025.txt │ ├── 00004_00026.txt │ ├── 00004_00027.txt │ ├── 00004_00028.txt │ ├── 00005_00001.txt │ ├── 00005_00002.txt │ ├── 00005_00003.txt │ ├── 00006.txt │ └── 00007.txt └── output │ ├── 00001.bmp │ ├── 00002.bmp │ ├── 00003.bmp │ ├── 00004.bmp │ ├── 00005.bmp │ ├── 00006.bmp │ └── 00007.bmp ├── GBP Case ├── Solid_GBP.stl └── Solid_GBP_Final.3mf ├── LICENSE ├── NeoGB_Printer ├── NeoGB_Printer.ino ├── PNGenc.cpp ├── Parse_ImageFile.ino ├── Parse_JSON_Config.ino ├── Parse_RAWData.ino ├── SD │ ├── NeoGB_paper_maker │ │ ├── Borders │ │ │ ├── Border_1.png │ │ │ ├── Border_10.png │ │ │ ├── Border_11.png │ │ │ ├── Border_12.png │ │ │ ├── Border_2.png │ │ │ ├── Border_3.png │ │ │ ├── Border_4.png │ │ │ ├── Border_5.png │ │ │ ├── Border_6.png │ │ │ ├── Border_7.png │ │ │ ├── Border_8.png │ │ │ └── Border_9.png │ │ ├── NeoGB_paper_maker.m │ │ ├── epaper_packet.m │ │ └── samplePixels │ │ │ ├── Pixel_sample_3600dpi_darkness_001.png │ │ │ ├── Pixel_sample_3600dpi_darkness_002.png │ │ │ ├── Pixel_sample_3600dpi_darkness_003.png │ │ │ ├── Pixel_sample_3600dpi_darkness_004.png │ │ │ ├── Pixel_sample_3600dpi_darkness_005.png │ │ │ ├── Pixel_sample_3600dpi_darkness_006.png │ │ │ ├── Pixel_sample_3600dpi_darkness_007.png │ │ │ ├── Pixel_sample_3600dpi_darkness_008.png │ │ │ ├── Pixel_sample_3600dpi_darkness_009.png │ │ │ └── Pixel_sample_3600dpi_darkness_010.png │ └── www │ │ ├── 57fb │ │ ├── remote.js │ │ └── remote.js.l.txt │ │ ├── conf.json │ │ ├── favicon.png │ │ ├── index.html │ │ ├── remote.css │ │ └── remote.html ├── WiFi_Server.ino ├── Wifi_Setup.ino ├── adler32.c ├── config.h presets │ ├── ESP32 Devkit 38pins │ │ └── config.h │ └── LilyGo TTGO-T2 │ │ └── config.h ├── config.h.txt ├── crc32.c ├── deflate.c ├── fs_setup.ino ├── gbp_pkt.cpp ├── gbp_serial_io.cpp ├── gbp_tiles.cpp ├── includes │ ├── StoreIDlib.h │ ├── display │ │ ├── SSD1306.hpp │ │ ├── SSD1331.hpp │ │ └── oled_graphics.h │ ├── gblink │ │ ├── gameboy_printer_protocol.h │ │ ├── gbp_cbuff.h │ │ ├── gbp_pkt.h │ │ ├── gbp_serial_io.h │ │ └── gbp_tiles.h │ ├── image │ │ ├── PNGenc │ │ │ ├── PNGenc.cpp │ │ │ ├── PNGenc.h │ │ │ ├── adler32.c │ │ │ ├── crc32.c │ │ │ ├── crc32.h │ │ │ ├── deflate.c │ │ │ ├── deflate.h │ │ │ ├── gzguts.h │ │ │ ├── png.h │ │ │ ├── trees.c │ │ │ ├── trees.h │ │ │ ├── zconf.h │ │ │ ├── zlib.h │ │ │ ├── zutil.c │ │ │ └── zutil.h │ │ ├── Upscalerlib.h │ │ ├── bmp_FixedWidthStream.h │ │ └── gbp_bmp.h │ └── led │ │ └── LED_status.h ├── oled.ino ├── trees.c └── zutil.c ├── NeoGB_Printer_PCB ├── Board Images │ ├── Bottom.svg │ └── Top.svg ├── ESP32_used.png ├── EasyEDA Project │ └── NeoGBP PCB.zip ├── Gerber_Files_NeoGBP.zip ├── LICENSE ├── NeoGBP_Schematic.pdf └── README.md ├── README.md ├── Supplementary_images ├── LinkCable.jpg ├── User_manual.png └── credits.png ├── displayImages ├── 128x32 │ ├── 1_splashscreen.png │ ├── 2_new_file.png │ ├── 3_SD_error.png │ ├── 4_Building_webserver.png │ ├── 4_Printer_idle.png │ ├── 4_Printer_idle2.png │ ├── 4_Printer_webserver.png │ ├── 4_Printer_webserver_2.jpg │ ├── 5_SD_full.png │ ├── 6_bin2bmp.png │ ├── 6_bin2png.png │ ├── 6_bmp2png.png │ ├── 6_bmpupscaling.png │ ├── 6_txt2bmp.png │ ├── 6_txt2png.png │ ├── 7_hex2bin.png │ ├── 7_hex2txt.png │ ├── 8_Seeking_date_time.png │ └── upscaling_image.png └── 96x64 │ ├── 1_splashscreen.png │ ├── 2_new_file.png │ ├── 3_SD_error.png │ ├── 4_Building_webserver.png │ ├── 4_Printer_idle.png │ ├── 4_Printer_idle2.png │ ├── 4_Printer_webserver.png │ ├── 4_Printer_webserver_2.png │ ├── 5_SD_full.png │ ├── 6_bin2bmp.png │ ├── 6_bin2png.png │ ├── 6_bmp2png.png │ ├── 6_bmpupscaling.png │ ├── 6_txt2bmp.png │ ├── 6_txt2png.png │ ├── 7_hex2bin.png │ ├── 7_hex2txt.png │ ├── 8_Seeking_date_time.png │ └── upscaling_image.png └── showcase ├── RaphaelBOICHOT.jpg ├── cristofercruz.jpg └── zenaro147.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | /NeoGB_Printer/config.h 2 | /NeoGB_Printer/.vscode/* 3 | /displayImages/helloOLED*.png 4 | /GBP Case/GBP Logo.png 5 | /GBP Case/Solid_GBP_Project.3mf 6 | /GBP Case/Prusa Projects/* 7 | /NeoGB_Printer/SD/www/output/* 8 | /NeoGB_Printer/SD/www/thumb/* 9 | /NeoGB_Printer_bkp/* -------------------------------------------------------------------------------- /Examples/dumps/00001_00001.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00001_00001.txt -------------------------------------------------------------------------------- /Examples/dumps/00001_00002.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00001_00002.txt -------------------------------------------------------------------------------- /Examples/dumps/00002_00001.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00002_00001.txt -------------------------------------------------------------------------------- /Examples/dumps/00002_00002.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00002_00002.txt -------------------------------------------------------------------------------- /Examples/dumps/00002_00003.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00002_00003.txt -------------------------------------------------------------------------------- /Examples/dumps/00003_00001.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00003_00001.txt -------------------------------------------------------------------------------- /Examples/dumps/00003_00002.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00003_00002.txt -------------------------------------------------------------------------------- /Examples/dumps/00003_00003.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00003_00003.txt -------------------------------------------------------------------------------- /Examples/dumps/00003_00004.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00003_00004.txt -------------------------------------------------------------------------------- /Examples/dumps/00003_00005.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00003_00005.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00001.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00001.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00002.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00002.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00003.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00003.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00004.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00004.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00005.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00005.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00006.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00006.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00007.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00007.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00008.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00008.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00009.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00009.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00010.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00010.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00011.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00011.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00012.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00012.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00013.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00013.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00014.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00014.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00015.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00015.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00016.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00016.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00017.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00017.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00018.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00018.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00019.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00019.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00020.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00020.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00021.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00021.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00022.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00022.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00023.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00023.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00024.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00024.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00025.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00025.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00026.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00026.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00027.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00027.txt -------------------------------------------------------------------------------- /Examples/dumps/00004_00028.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00004_00028.txt -------------------------------------------------------------------------------- /Examples/dumps/00005_00001.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00005_00001.txt -------------------------------------------------------------------------------- /Examples/dumps/00005_00002.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00005_00002.txt -------------------------------------------------------------------------------- /Examples/dumps/00005_00003.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00005_00003.txt -------------------------------------------------------------------------------- /Examples/dumps/00006.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00006.txt -------------------------------------------------------------------------------- /Examples/dumps/00007.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/dumps/00007.txt -------------------------------------------------------------------------------- /Examples/output/00001.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00001.bmp -------------------------------------------------------------------------------- /Examples/output/00002.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00002.bmp -------------------------------------------------------------------------------- /Examples/output/00003.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00003.bmp -------------------------------------------------------------------------------- /Examples/output/00004.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00004.bmp -------------------------------------------------------------------------------- /Examples/output/00005.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00005.bmp -------------------------------------------------------------------------------- /Examples/output/00006.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00006.bmp -------------------------------------------------------------------------------- /Examples/output/00007.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Examples/output/00007.bmp -------------------------------------------------------------------------------- /GBP Case/Solid_GBP.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/GBP Case/Solid_GBP.stl -------------------------------------------------------------------------------- /GBP Case/Solid_GBP_Final.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/GBP Case/Solid_GBP_Final.3mf -------------------------------------------------------------------------------- /NeoGB_Printer/PNGenc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // PNG Decoder 3 | // 4 | // written by Larry Bank 5 | // bitbank@pobox.com 6 | // Arduino port started 5/3/2021 7 | // Original PNG code written 20+ years ago :) 8 | // The goal of this code is to decode PNG images on embedded systems 9 | // 10 | // Copyright 2021 BitBank Software, Inc. All Rights Reserved. 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | //=========================================================================== 21 | // 22 | #include "./includes/image/PNGenc/PNGenc.h" 23 | 24 | // Include the C code which does the actual work 25 | #include "./includes/image/PNGenc/png.h" 26 | 27 | // 28 | // File (SD/MMC) based initialization 29 | // 30 | int PNG::open(const char *szFilename, PNG_OPEN_CALLBACK *pfnOpen, PNG_CLOSE_CALLBACK *pfnClose, PNG_READ_CALLBACK *pfnRead, PNG_WRITE_CALLBACK *pfnWrite, PNG_SEEK_CALLBACK *pfnSeek) 31 | { 32 | memset(&_png, 0, sizeof(PNGIMAGE)); 33 | _png.iTransparent = -1; 34 | _png.pfnRead = pfnRead; 35 | _png.pfnWrite = pfnWrite; 36 | _png.pfnSeek = pfnSeek; 37 | _png.pfnOpen = pfnOpen; 38 | _png.pfnClose = pfnClose; 39 | _png.PNGFile.fHandle = (*pfnOpen)(szFilename); 40 | if (_png.PNGFile.fHandle == NULL) { 41 | _png.iError = PNG_INVALID_FILE; 42 | return PNG_INVALID_FILE; 43 | } 44 | return PNG_SUCCESS; 45 | 46 | } /* open() */ 47 | 48 | int PNG::open(uint8_t *pOutput, int iBufferSize) 49 | { 50 | memset(&_png, 0, sizeof(PNGIMAGE)); 51 | _png.iTransparent = -1; 52 | _png.pOutput = pOutput; 53 | _png.iBufferSize = iBufferSize; 54 | return PNG_SUCCESS; 55 | } /* open() */ 56 | 57 | // 58 | // return the last error (if any) 59 | // 60 | int PNG::getLastError() 61 | { 62 | return _png.iError; 63 | } /* getLastError() */ 64 | // 65 | // Close the file - not needed when decoding from memory 66 | // 67 | int PNG::close() 68 | { 69 | if (_png.pfnClose) 70 | (*_png.pfnClose)(&_png.PNGFile); 71 | return _png.iDataSize; 72 | } /* close() */ 73 | 74 | int PNG::encodeBegin(int iWidth, int iHeight, uint8_t ucPixelType, uint8_t ucBpp, uint8_t *pPalette, uint8_t ucCompLevel) 75 | { 76 | _png.iWidth = iWidth; 77 | _png.iHeight = iHeight; 78 | _png.ucPixelType = ucPixelType; 79 | _png.ucBpp = ucBpp; 80 | if (pPalette != NULL) 81 | memcpy(_png.ucPalette, pPalette, 768); // save 256 color entries 82 | _png.ucCompLevel = ucCompLevel; 83 | _png.y = 0; 84 | return PNG_SUCCESS; 85 | } /* encodeBegin() */ 86 | 87 | int PNG::addLine(uint8_t *pPixels) 88 | { 89 | int rc; 90 | rc = PNGAddLine(&_png, pPixels, _png.y); 91 | _png.y++; 92 | return rc; 93 | } /* addLine() */ 94 | 95 | int PNG::setTransparentColor(uint32_t u32Color) 96 | { 97 | if (_png.ucPixelType == PNG_PIXEL_GRAYSCALE || _png.ucPixelType == PNG_PIXEL_TRUECOLOR) { 98 | _png.iTransparent = u32Color; 99 | return PNG_SUCCESS; 100 | } 101 | else 102 | return PNG_INVALID_PARAMETER; // indexed image must have palette alpha values 103 | } /* setTransparentColor() */ 104 | 105 | int PNG::setAlphaPalette(uint8_t *pPalette) 106 | { 107 | if (pPalette != NULL && _png.ucPixelType == PNG_PIXEL_INDEXED) { 108 | _png.ucHasAlphaPalette = 1; 109 | memcpy(&_png.ucPalette[768], pPalette, 256); // capture up to 256 alpha values 110 | return PNG_SUCCESS; 111 | } 112 | return PNG_INVALID_PARAMETER; 113 | } /* setAlphaPalette() */ 114 | -------------------------------------------------------------------------------- /NeoGB_Printer/Parse_RAWData.ino: -------------------------------------------------------------------------------- 1 | //Useful to print the serial data into the Serial Monitor 2 | //#define DEBUG_SERIAL 3 | 4 | uint8_t dtpck = 0; 5 | 6 | const char nibbleToCharLUT[] = "0123456789ABCDEF"; 7 | byte img_tmp[6000] = {}; // 1GBC Picute (5.874) 8 | 9 | TaskHandle_t TaskWriteDump; 10 | /******************************************************************************* 11 | Recieve Raw Data from GameBoy 12 | *******************************************************************************/ 13 | inline void gbp_packet_capture_loop() { 14 | /* tiles received */ 15 | static uint32_t byteTotal = 0; 16 | static uint32_t pktTotalCount = 0; 17 | static uint32_t pktByteIndex = 0; 18 | static uint16_t pktDataLength = 0; 19 | const size_t dataBuffCount = gbp_serial_io_dataBuff_getByteCount(); 20 | if ( 21 | ((pktByteIndex != 0) && (dataBuffCount > 0)) || 22 | ((pktByteIndex == 0) && (dataBuffCount >= 6)) 23 | ) { 24 | uint8_t data_8bit = 0; 25 | 26 | // Display the data payload encoded in hex 27 | for (int i = 0 ; i < dataBuffCount ; i++) { 28 | // Start of a new packet 29 | if (pktByteIndex == 0) { 30 | pktDataLength = gbp_serial_io_dataBuff_getByte_Peek(4); 31 | pktDataLength |= (gbp_serial_io_dataBuff_getByte_Peek(5) << 8) & 0xFF00; 32 | 33 | #ifdef USE_OLED 34 | oledStateChange(4); //HEX to BIN 35 | #endif 36 | chkHeader = (int)gbp_serial_io_dataBuff_getByte_Peek(2); 37 | 38 | switch (chkHeader) { 39 | case 1: 40 | isPrinting = true; 41 | chkMargin = 0x00; 42 | memset(image_data, 0x00, sizeof(image_data)); 43 | img_index = 0x00; 44 | break; 45 | case 4: 46 | ////////////////////////////////////////////// FIX for merge print in McDonald's Monogatari : Honobono Tenchou Ikusei Game and Nakayoshi Cooking Series 5 : Cake o Tsukurou ////////////////////////////////////////////// 47 | if (pktDataLength > 0){ 48 | //Count how many data packages was received before sending the print command 49 | dtpck++; 50 | } 51 | ////////////////////////////////////////////// FIX for merge print in McDonald's Monogatari : Honobono Tenchou Ikusei Game and Nakayoshi Cooking Series 5 : Cake o Tsukurou ////////////////////////////////////////////// 52 | break; 53 | default: 54 | break; 55 | } 56 | #ifdef LED_STATUS_PIN 57 | LED_led_ON(LED_STATUS_PIN); 58 | #endif 59 | #if defined(COMMON_ANODE) || defined(COMMON_CATHODE) 60 | LED_led_ON(LED_STATUS_GREEN); 61 | #endif 62 | 63 | #ifdef DEBUG_SERIAL 64 | Serial.print("// "); 65 | Serial.print(pktTotalCount); 66 | Serial.print(" : "); 67 | Serial.println(gbpCommand_toStr(gbp_serial_io_dataBuff_getByte_Peek(2))); 68 | #endif 69 | } 70 | 71 | data_8bit = gbp_serial_io_dataBuff_getByte(); 72 | 73 | #ifdef DEBUG_SERIAL 74 | // Print Hex Byte 75 | Serial.print((char)nibbleToCharLUT[(data_8bit>>4)&0xF]); 76 | Serial.print((char)nibbleToCharLUT[(data_8bit>>0)&0xF]); 77 | #endif 78 | 79 | if (chkHeader == 1 || chkHeader == 2 || chkHeader == 4){ 80 | image_data[img_index] = (byte)data_8bit; 81 | img_index++; 82 | if (chkHeader == 2 && pktByteIndex == 7) { 83 | chkMargin = (int)((char)nibbleToCharLUT[(data_8bit>>0)&0xF])-'0'; 84 | } 85 | } 86 | 87 | if ((pktByteIndex > 5) && (pktByteIndex >= (9 + pktDataLength))) { 88 | #ifdef LED_STATUS_PIN 89 | LED_led_OFF(LED_STATUS_PIN); 90 | #endif 91 | #if defined(COMMON_ANODE) || defined(COMMON_CATHODE) 92 | LED_led_OFF(LED_STATUS_GREEN); 93 | #endif 94 | if (chkHeader == 2 && !isWriting) { 95 | memcpy(img_tmp,image_data,6000); 96 | memset(image_data, 0x00, sizeof(image_data)); 97 | isWriting=true; 98 | if((chkMargin == 0 || ((chkMargin == 3 && dtpck == 1) || (chkMargin == 1 && dtpck == 1) || (chkMargin == 1 && dtpck == 6))) && !setMultiPrint){ 99 | setMultiPrint=true; 100 | dtpck=0x00; 101 | }else if(chkMargin > 0 && setMultiPrint){ 102 | setMultiPrint=false; 103 | } 104 | xTaskCreatePinnedToCore(storeData, // Task function. 105 | "storeData", // name of task. 106 | 10000, // Stack size of task 107 | (void*)&img_tmp, // parameter of the task 108 | 1, // priority of the task 109 | &TaskWriteDump, // Task handle to keep track of created task 110 | 0); // pin task to core 0 111 | dtpck = 0x00; 112 | } 113 | #ifdef DEBUG_SERIAL 114 | Serial.println(""); 115 | #endif 116 | pktByteIndex = 0; 117 | pktTotalCount++; 118 | } else { 119 | #ifdef DEBUG_SERIAL 120 | Serial.print((char)' '); 121 | #endif 122 | pktByteIndex++; // Byte hex split counter 123 | byteTotal++; // Byte total counter 124 | } 125 | } 126 | } 127 | } 128 | 129 | /******************************************************************************* 130 | Write HEX dump file 131 | *******************************************************************************/ 132 | void storeData(void *pvParameters) { 133 | unsigned long perf = millis(); 134 | int img_index2=img_index; 135 | byte *image_data2 = ((byte*)pvParameters); 136 | img_index = 0x00; 137 | 138 | char fileName[31]; 139 | byte inqypck[10] = {B10001000, B00110011, B00001111, B00000000, B00000000, B00000000, B00001111, B00000000, B10000001, B00000000}; 140 | 141 | if(setMultiPrint || totalMultiImages > 1){ 142 | sprintf(fileName, "/dumps/%05d_%05d.bin", freeFileIndex,totalMultiImages); 143 | }else{ 144 | sprintf(fileName, "/dumps/%05d.bin", freeFileIndex); 145 | } 146 | 147 | File file = FSYS.open(fileName, FILE_WRITE); 148 | if (!file) { 149 | Serial.println("file creation failed"); 150 | } 151 | file.write(image_data2, img_index2); 152 | file.write(inqypck, 10); 153 | file.close(); 154 | 155 | perf = millis() - perf; 156 | if(setMultiPrint || totalMultiImages > 1){ 157 | Serial.printf("File /dumps/%05d_%05d.bin written in %lums\n", freeFileIndex,totalMultiImages,perf); 158 | }else{ 159 | Serial.printf("File /dumps/%05d.bin written in %lums\n", freeFileIndex, perf); 160 | } 161 | 162 | //Check how much space still have 163 | uint8_t percUsed = fs_info(); 164 | if (percUsed > 10) { 165 | if(!setMultiPrint){ 166 | isPrinting = false; 167 | freeFileIndex=update_get_next_ID(1); 168 | totalMultiImages=1; //fix to enforce correct printing with Blargle1290 169 | dumpCount = update_get_dumps(1); 170 | }else{ 171 | totalMultiImages++; 172 | } 173 | //Reset Variables 174 | Serial.println("Printer ready."); 175 | isWriting = false; 176 | 177 | } else { 178 | full(); 179 | } 180 | vTaskDelete(NULL); 181 | } 182 | 183 | /******************************************************************************* 184 | Force to call the next file 185 | (fix for Mary-Kate and Ashley Pocket Planner / E.T.: Digital Companion / 186 | McDonald's Monogatari : Honobono Tenchou Ikusei Game) 187 | *******************************************************************************/ 188 | void ResetPrinterVariables(){ 189 | Serial.println("Reseting Vars..."); 190 | //Reset Variables 191 | setMultiPrint = false; 192 | totalMultiImages = 1; 193 | img_index = 0x00; 194 | chkHeader = 99; 195 | isWriting = false; 196 | isPrinting = false; 197 | memset(image_data, 0x00, sizeof(image_data)); 198 | 199 | Serial.println("Printer Ready"); 200 | } 201 | -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_1.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_10.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_11.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_12.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_2.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_3.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_4.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_5.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_6.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_7.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_8.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/Borders/Border_9.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/NeoGB_paper_maker.m: -------------------------------------------------------------------------------- 1 | % Raphael BOICHOT 25/11/2021 E-paper module for NeoGB printer 2 | % multi OS compatibility improved by Cristofer Cruz 2022/06/21 3 | % Compatible with Matlab and Octave 4 | % image must be 4 colors maximum, which is the native output format 5 | clear 6 | clc 7 | 8 | paper_color=1; %6=random, 5=purple, 4=pink, 3=regular blue, 2=regular yellow or 1=regular white 9 | darkness=10; %1=lightest 10=darkest 10 | scale_percentage=30; %100=full size, smaller values scale down image 11 | 12 | %watermarking='Raphael BOICHOT 2021'; 13 | 14 | try 15 | pkg load image % for compatibility with Octave 16 | catch 17 | % Nothing to do 18 | end 19 | 20 | root=pwd; 21 | mkdir Paper_out 22 | imagefiles = dir([root(1:3),'\www\thumb\*.png']);% the default format is png, other are ignored 23 | nfiles = length(imagefiles); % Number of files found 24 | 25 | for k=1:1:nfiles 26 | currentfilename = imagefiles(k).name; 27 | BandW_image=imread([root(1:3),'\www\thumb\',currentfilename]); 28 | map=BandW_image(:,:,1); 29 | C=unique(map); 30 | switch length(C) 31 | case 4; map=(map==C(1))*0+(map==C(2))*84+(map==C(3))*168+(map==C(4))*255; 32 | case 3; map=(map==C(1))*0+(map==C(2))*84+(map==C(3))*255; 33 | case 2; map=(map==C(1))*0+(map==C(2))*255; 34 | end; 35 | [epaper, alpha]=epaper_packet(map,paper_color,darkness,scale_percentage); 36 | imwrite(epaper,['Paper_out/printerPaper-dark',num2str(darkness),'-',currentfilename],'Alpha',alpha); 37 | disp(['printerPaper-dark',num2str(darkness),'-',currentfilename,' saved.']) 38 | end 39 | disp('Done!') 40 | 41 | -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/epaper_packet.m: -------------------------------------------------------------------------------- 1 | function [output, alpha]=epaper_packet(input,paper_color,darkness,scale_percentage) 2 | % Raphael BOICHOT 10-09-2020 3 | % multi OS compatibility improved by Cristofer Cruz 2022/06/21 4 | % code to simulate the speckle aspect of real Game boy printer 5 | % image come from function call 6 | 7 | sourceborders = dir('Borders/*.png'); 8 | pixel_sample=imread(['samplePixels/Pixel_sample_3600dpi_darkness_',num2str(darkness,'%03.f'),'.png']); 9 | num_borders=numel(sourceborders);%number of border images in the library 10 | num1=ceil(num_borders*rand); 11 | num2=num1; 12 | while num1==num2 13 | num2=ceil(num_borders*rand); 14 | end 15 | 16 | border_1=imread(['Borders/Border_',num2str(num1),'.png']); 17 | border_2=imread(['Borders/Border_',num2str(num2),'.png']); 18 | IMAGE=input; 19 | 20 | mul=20;%size of the mask 21 | overlapping=4;%overlapping 22 | 23 | %intensity map for printer head with threshold 24 | [heigth, width,~]=size(IMAGE); 25 | streaks=zeros(heigth, width); 26 | for i=1:1:width 27 | start=ceil(2*rand)-1; 28 | for j=1:1:heigth 29 | streaks(j,i)=start; 30 | %you can change the streak length here 31 | if rand<0.2;start=ceil(2*rand)-1;end; 32 | end 33 | end 34 | 35 | speckle_image=uint8(255*ones(heigth*(mul-overlapping)+overlapping,width*(mul-overlapping)+overlapping,3)); 36 | 37 | for i=1:1:heigth 38 | for j=1:1:width 39 | a=1+(i-1)*(mul-overlapping); 40 | b=a+mul-1; 41 | c=1+(j-1)*(mul-overlapping); 42 | d=c+mul-1; 43 | if IMAGE(i,j)==0 44 | y=0; 45 | x=ceil(49*rand); 46 | burn_dot=pixel_sample(1+20*y:20+20*y,1+20*x:20+20*x,:); 47 | end 48 | 49 | if IMAGE(i,j)==84 50 | y=1; 51 | x=ceil(49*rand); 52 | burn_dot=pixel_sample(1+20*y:20+20*y,1+20*x:20+20*x,:); 53 | end 54 | 55 | if IMAGE(i,j)==168 56 | y=2; 57 | x=ceil(49*rand); 58 | burn_dot=pixel_sample(1+20*y:20+20*y,1+20*x:20+20*x,:); 59 | end 60 | 61 | if not(IMAGE(i,j)==255); 62 | if rand<0.5; burn_dot=flip(burn_dot,ceil(2*rand));end; 63 | burn_dot=rot90(burn_dot,ceil(2*rand)-2); 64 | if streaks(i,j)==0; burn_dot=burn_dot+15;end; 65 | speckle_image(a:b,c:d,:)=min(burn_dot,speckle_image(a:b,c:d,:)); 66 | end 67 | end 68 | end 69 | %centering image on paper, The width of the print should be 27.09mm compared to the paper at 38mm 70 | [V,W,~]=size(speckle_image); 71 | add_col=round((W*38/27.9)-W)/2; 72 | vert_borders=255*ones(V,add_col,3); 73 | speckle_image=[vert_borders,speckle_image,vert_borders]; 74 | %adding margins same size as lateral white borders 75 | horz_borders=255*ones(add_col,add_col*2+W,3); 76 | speckle_image=[horz_borders;speckle_image;horz_borders]; 77 | %adding some subtle image noise 78 | surface_in_pixels=V*W; 79 | dot_rate=surface_in_pixels/200000; 80 | for i=1:1:dot_rate 81 | I=ceil(rand*(V-mul)); 82 | J=ceil(rand*(W-mul)); 83 | y=2; 84 | x=ceil(49*rand); 85 | burn_dot=pixel_sample(1+20*y:20+20*y,1+20*x:20+20*x,:)+100; 86 | if rand<0.5; burn_dot=flip(burn_dot,ceil(2*rand));end; 87 | burn_dot=rot90(burn_dot,ceil(2*rand)-2); 88 | speckle_image(I:I+mul-1,J:J+mul-1,:)=min(burn_dot,speckle_image(I:I+mul-1,J:J+mul-1,:)); 89 | end 90 | %resizing everything 91 | resize_ratio=scale_percentage/100; %1 for full image, 0.3 for nice looking image 92 | border1_resized=imresize(border_1,resize_ratio); 93 | if rand<0.5,border1_resized=fliplr(border1_resized);end; 94 | border2_resized=imresize(border_2,resize_ratio); 95 | if rand<0.5,border2_resized=fliplr(border2_resized);end; 96 | speckle_image=imresize(speckle_image,resize_ratio); 97 | %creating the alpha layer from black pixels 98 | [V,W,~]=size(speckle_image); 99 | alpha_layer1=(border1_resized(:,:,1)); 100 | alpha_layer2=(border2_resized(:,:,1)); 101 | alpha_central=255*ones(V,W); 102 | speckle_image=[fliplr(flipud(border1_resized));speckle_image;border2_resized]; 103 | alpha=[fliplr(flipud(alpha_layer1));alpha_central;alpha_layer2]; 104 | %coloring the paper 105 | if (paper_color==6) 106 | speckle_image(:,:,1)=speckle_image(:,:,1)*((255-ceil(35*rand))/255); 107 | speckle_image(:,:,2)=speckle_image(:,:,2)*((255-ceil(35*rand))/255); 108 | speckle_image(:,:,3)=speckle_image(:,:,3)*((255-ceil(35*rand))/255); 109 | end 110 | if (paper_color==5) 111 | speckle_image(:,:,1)=speckle_image(:,:,1)*(242/255); 112 | speckle_image(:,:,2)=speckle_image(:,:,2)*(230/255); 113 | speckle_image(:,:,3)=speckle_image(:,:,3)*(255/255); 114 | end 115 | if (paper_color==4) 116 | speckle_image(:,:,1)=speckle_image(:,:,1)*(255/255); 117 | speckle_image(:,:,2)=speckle_image(:,:,2)*(221/255); 118 | speckle_image(:,:,3)=speckle_image(:,:,3)*(232/255); 119 | end 120 | if (paper_color==3) 121 | speckle_image(:,:,1)=speckle_image(:,:,1)*(220/255); 122 | speckle_image(:,:,2)=speckle_image(:,:,2)*(250/255); 123 | speckle_image(:,:,3)=speckle_image(:,:,3)*(242/255); 124 | end 125 | if (paper_color==2) 126 | speckle_image(:,:,1)=speckle_image(:,:,1)*(247/255); 127 | speckle_image(:,:,2)=speckle_image(:,:,2)*(250/255); 128 | speckle_image(:,:,3)=speckle_image(:,:,3)*(220/255); 129 | end 130 | if (paper_color==1) 131 | end 132 | output=speckle_image; 133 | 134 | -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_001.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_002.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_003.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_004.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_005.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_006.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_007.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_008.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_009.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/NeoGB_paper_maker/samplePixels/Pixel_sample_3600dpi_darkness_010.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/www/57fb/remote.js.l.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | localForage -- Offline Storage, Improved 3 | Version 1.9.0 4 | https://localforage.github.io/localForage 5 | (c) 2013-2017 Mozilla, Apache License 2.0 6 | */ 7 | 8 | /*! 9 | * The buffer module from node.js, for the browser. 10 | * 11 | * @author Feross Aboukhadijeh 12 | * @license MIT 13 | */ 14 | -------------------------------------------------------------------------------- /NeoGB_Printer/SD/www/conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "mdns": "gbprinter", 3 | "ap": { 4 | "ssid":"gbprinter", 5 | "psk":"gbprinter" 6 | }, 7 | "network": { 8 | "ssid":"Your SSID", 9 | "psk":"Your wifi password" 10 | }, 11 | "bmpimage": { 12 | "scale":1 13 | }, 14 | "pngimage": { 15 | "scale":1 16 | } 17 | } -------------------------------------------------------------------------------- /NeoGB_Printer/SD/www/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer/SD/www/favicon.png -------------------------------------------------------------------------------- /NeoGB_Printer/SD/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Game Boy Printer Gallery 7 | 148 | 168 | 169 | 170 |

Game Boy Printer Gallery

171 |
172 | 173 | 174 |
175 | Refresh List 176 |
177 | 178 | 179 | 180 | 181 | 186 | 187 | 188 | 201 | 202 | 203 | 223 | 224 | 225 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /NeoGB_Printer/SD/www/remote.css: -------------------------------------------------------------------------------- 1 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,menu,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,main,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section{display:block}*[hidden]{display:none}body{line-height:1}menu,ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}*{-webkit-box-sizing:border-box;box-sizing:border-box}body{font-family:"Trebuchet MS", Helvetica, sans-serif;line-height:1.3em;background-color:#d6d3dc;color:#333;min-width:21.25rem;overflow-y:scroll}html.theme-dark body{background-color:#2a292b}html.theme-dark body{color:#b2b2b2}body.has-overlay{position:fixed;width:100vw}pre{font-family:monospace;font-size:0.875rem;height:auto;overflow-y:scroll;display:block;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.init-error{margin:3.75rem;padding:1.25rem 1.875rem;border:8px solid;overflow-x:auto;border-color:#292037;background-color:#4c4c4c;color:#b2b2b2}html.theme-dark .init-error{border-color:#455c63}html.theme-dark .init-error{background-color:#b2b2b2}html.theme-dark .init-error{color:#333}@media (max-width: 37.5rem){.init-error{margin:3.75rem 0.625rem;padding:1.25rem 0.625rem}}.init-error small{display:block;font-size:0.75rem;line-height:1rem;margin-top:1.875rem;white-space:pre}.remote-info{font-size:1rem;margin-bottom:0.938rem;display:none}.remote-info--ip{color:#1a1a1a}html.theme-dark .remote-info--ip{color:#e5e5e5}.remote-info--em{color:red}html.theme-dark .remote-info--em{color:#cb0003}body{padding:1.25rem} 2 | 3 | -------------------------------------------------------------------------------- /NeoGB_Printer/SD/www/remote.html: -------------------------------------------------------------------------------- 1 | Gameboy Printer Remote

This window is missing the reference to your main app.

It must be opened from the settings page of your main app in order to work!

This is a remote window which is included in an iframe on your main page. You should not see this message.

This is your WiFi-printer's remote control page.

You can go back to your main app and start importing your images.

In order for the import to work, this window needs to remain open!

-------------------------------------------------------------------------------- /NeoGB_Printer/Wifi_Setup.ino: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | bool hasNetworkSettings = true; 3 | String ip = ""; 4 | 5 | void initWifi(){ 6 | hasNetworkSettings = loadWiFiConfig(); //Get Data from the conf.json 7 | 8 | const char * accesPointSSIDc = accesPointSSID.c_str(); 9 | const char * accesPointPasswordc = accesPointPassword.c_str(); 10 | const char * accesPointSSIDLc = accesPointSSIDLocal.c_str(); 11 | const char * accesPointPasswordLc = accesPointPasswordLocal.c_str(); 12 | 13 | WiFi.disconnect(); 14 | Serial.print("Connecting to wifi "); 15 | WiFi.mode(WIFI_MODE_STA); 16 | WiFi.begin(accesPointSSIDc, accesPointPasswordc); 17 | WiFi.setSleep(false); 18 | 19 | unsigned int connTimeout = millis() + WIFI_CONNECT_TIMEOUT; 20 | unsigned int connTick = 0; 21 | while (hasNetworkSettings && (WiFi.status() != WL_CONNECTED)) { 22 | delay(250); 23 | connTick++; 24 | 25 | unsigned int remain = connTimeout - millis(); 26 | if (remain <= 0 || remain > WIFI_CONNECT_TIMEOUT) { 27 | Serial.println("WiFi Connection timeout"); 28 | hasNetworkSettings = false; 29 | } 30 | 31 | if (connTick % 4 == 0) { 32 | Serial.print("."); 33 | //STATUS CONNECTING 34 | } 35 | } 36 | 37 | if (hasNetworkSettings) { 38 | Serial.print("\nConnected to "); 39 | Serial.print(WiFi.SSID()); 40 | Serial.print(" with IP address: "); 41 | Serial.println(WiFi.localIP()); 42 | 43 | //Get Time from NTP Server (Article about RTC/NTP for ESP32: http://suadica.com/dica.php?d=439&t=como-utilizar-relogio-rtc-interno-do-esp32) 44 | ntp.begin(); 45 | ntp.forceUpdate(); 46 | Serial.print("Updating Date and Time..."); 47 | datetime = ntp.getEpochTime(); 48 | Serial.print("NTP Unix: "); 49 | Serial.println(datetime); 50 | timeval tv; 51 | tv.tv_sec = datetime; 52 | settimeofday(&tv, NULL); 53 | time_t tt = time(NULL); 54 | data = *gmtime(&tt); 55 | strftime(formatted_datetime, 64, "%d/%m/%Y %H:%M:%S", &data); 56 | Serial.print("Date and Time updated: "); 57 | Serial.println(formatted_datetime); 58 | 59 | } else { 60 | WiFi.mode(WIFI_MODE_AP); 61 | WiFi.softAP(accesPointSSIDLc, accesPointPasswordLc); 62 | Serial.println("AccessPoint started"); 63 | } 64 | } 65 | 66 | #ifdef ENABLE_WEBSERVER 67 | void mdns_setup() { 68 | loadMdnsConfig(); 69 | String protocol = F("http://"); 70 | String localsrv = ".local"; 71 | 72 | const char * mdnsNamec = mdnsName.c_str(); 73 | if (!MDNS.begin(mdnsNamec)) { 74 | Serial.println("Error setting up MDNS responder!"); 75 | } 76 | 77 | MDNS.addService("http", "tcp", 80); 78 | WiFi.hostname(mdnsName + localsrv); 79 | 80 | Serial.println("mDNS responder started"); 81 | 82 | if (hasNetworkSettings) { 83 | ip = WiFi.localIP().toString(); 84 | } else { 85 | ip = WiFi.softAPIP().toString(); 86 | } 87 | 88 | Serial.println(protocol + ip); 89 | Serial.println(protocol + mdnsName); 90 | Serial.println(protocol + mdnsName + localsrv); 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /NeoGB_Printer/adler32.c: -------------------------------------------------------------------------------- 1 | /* adler32.c -- compute the Adler-32 checksum of a data stream 2 | * Copyright (C) 1995-2011, 2016 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "./includes/image/PNGenc/zutil.h" 9 | 10 | local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); 11 | 12 | #define BASE 65521U /* largest prime smaller than 65536 */ 13 | #define NMAX 5552 14 | /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 15 | 16 | #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} 17 | #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 18 | #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 19 | #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 20 | #define DO16(buf) DO8(buf,0); DO8(buf,8); 21 | 22 | /* use NO_DIVIDE if your processor does not do division in hardware -- 23 | try it both ways to see which is faster */ 24 | #ifdef NO_DIVIDE 25 | /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 26 | (thank you to John Reiser for pointing this out) */ 27 | # define CHOP(a) \ 28 | do { \ 29 | unsigned long tmp = a >> 16; \ 30 | a &= 0xffffUL; \ 31 | a += (tmp << 4) - tmp; \ 32 | } while (0) 33 | # define MOD28(a) \ 34 | do { \ 35 | CHOP(a); \ 36 | if (a >= BASE) a -= BASE; \ 37 | } while (0) 38 | # define MOD(a) \ 39 | do { \ 40 | CHOP(a); \ 41 | MOD28(a); \ 42 | } while (0) 43 | # define MOD63(a) \ 44 | do { /* this assumes a is not negative */ \ 45 | z_off64_t tmp = a >> 32; \ 46 | a &= 0xffffffffL; \ 47 | a += (tmp << 8) - (tmp << 5) + tmp; \ 48 | tmp = a >> 16; \ 49 | a &= 0xffffL; \ 50 | a += (tmp << 4) - tmp; \ 51 | tmp = a >> 16; \ 52 | a &= 0xffffL; \ 53 | a += (tmp << 4) - tmp; \ 54 | if (a >= BASE) a -= BASE; \ 55 | } while (0) 56 | #else 57 | # define MOD(a) a %= BASE 58 | # define MOD28(a) a %= BASE 59 | # define MOD63(a) a %= BASE 60 | #endif 61 | 62 | /* ========================================================================= */ 63 | uLong ZEXPORT adler32_z(adler, buf, len) 64 | uLong adler; 65 | const Bytef *buf; 66 | z_size_t len; 67 | { 68 | unsigned long sum2; 69 | unsigned n; 70 | 71 | /* split Adler-32 into component sums */ 72 | sum2 = (adler >> 16) & 0xffff; 73 | adler &= 0xffff; 74 | 75 | /* in case user likes doing a byte at a time, keep it fast */ 76 | if (len == 1) { 77 | adler += buf[0]; 78 | if (adler >= BASE) 79 | adler -= BASE; 80 | sum2 += adler; 81 | if (sum2 >= BASE) 82 | sum2 -= BASE; 83 | return adler | (sum2 << 16); 84 | } 85 | 86 | /* initial Adler-32 value (deferred check for len == 1 speed) */ 87 | if (buf == Z_NULL) 88 | return 1L; 89 | 90 | /* in case short lengths are provided, keep it somewhat fast */ 91 | if (len < 16) { 92 | while (len--) { 93 | adler += *buf++; 94 | sum2 += adler; 95 | } 96 | if (adler >= BASE) 97 | adler -= BASE; 98 | MOD28(sum2); /* only added so many BASE's */ 99 | return adler | (sum2 << 16); 100 | } 101 | 102 | /* do length NMAX blocks -- requires just one modulo operation */ 103 | while (len >= NMAX) { 104 | len -= NMAX; 105 | n = NMAX / 16; /* NMAX is divisible by 16 */ 106 | do { 107 | DO16(buf); /* 16 sums unrolled */ 108 | buf += 16; 109 | } while (--n); 110 | MOD(adler); 111 | MOD(sum2); 112 | } 113 | 114 | /* do remaining bytes (less than NMAX, still just one modulo) */ 115 | if (len) { /* avoid modulos if none remaining */ 116 | while (len >= 16) { 117 | len -= 16; 118 | DO16(buf); 119 | buf += 16; 120 | } 121 | while (len--) { 122 | adler += *buf++; 123 | sum2 += adler; 124 | } 125 | MOD(adler); 126 | MOD(sum2); 127 | } 128 | 129 | /* return recombined sums */ 130 | return adler | (sum2 << 16); 131 | } 132 | 133 | /* ========================================================================= */ 134 | uLong ZEXPORT adler32(adler, buf, len) 135 | uLong adler; 136 | const Bytef *buf; 137 | uInt len; 138 | { 139 | return adler32_z(adler, buf, len); 140 | } 141 | 142 | /* ========================================================================= */ 143 | local uLong adler32_combine_(adler1, adler2, len2) 144 | uLong adler1; 145 | uLong adler2; 146 | z_off64_t len2; 147 | { 148 | unsigned long sum1; 149 | unsigned long sum2; 150 | unsigned rem; 151 | 152 | /* for negative len, return invalid adler32 as a clue for debugging */ 153 | if (len2 < 0) 154 | return 0xffffffffUL; 155 | 156 | /* the derivation of this formula is left as an exercise for the reader */ 157 | MOD63(len2); /* assumes len2 >= 0 */ 158 | rem = (unsigned)len2; 159 | sum1 = adler1 & 0xffff; 160 | sum2 = rem * sum1; 161 | MOD(sum2); 162 | sum1 += (adler2 & 0xffff) + BASE - 1; 163 | sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 164 | if (sum1 >= BASE) sum1 -= BASE; 165 | if (sum1 >= BASE) sum1 -= BASE; 166 | if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); 167 | if (sum2 >= BASE) sum2 -= BASE; 168 | return sum1 | (sum2 << 16); 169 | } 170 | 171 | /* ========================================================================= */ 172 | uLong ZEXPORT adler32_combine(adler1, adler2, len2) 173 | uLong adler1; 174 | uLong adler2; 175 | z_off_t len2; 176 | { 177 | return adler32_combine_(adler1, adler2, len2); 178 | } 179 | 180 | uLong ZEXPORT adler32_combine64(adler1, adler2, len2) 181 | uLong adler1; 182 | uLong adler2; 183 | z_off64_t len2; 184 | { 185 | return adler32_combine_(adler1, adler2, len2); 186 | } 187 | -------------------------------------------------------------------------------- /NeoGB_Printer/config.h presets/ESP32 Devkit 38pins/config.h: -------------------------------------------------------------------------------- 1 | /********************************* 2 | * GAMEBOY LINK CABLE DEFINITIONS 3 | *********************************/ 4 | // Note: Serial Clock Pin must be attached to an interrupt pin of the ESP (Pins 1 and 4 are not used. Pin 6 must be connect to the GND) 5 | // ___________ 6 | // | 6 4 2 | 7 | // \_5__3__1_/ (at cable) 8 | // 9 | #define ESP_MOSI_PIN 23 10 | #define ESP_MISO_PIN 19 11 | #define ESP_CLK_PIN 18 12 | //#define INVERT_SERIAL_PINS //Invert pin 2 and 3 order, since the pin 2 goes o 3 in the other side of the cable, and 3 goes to 2. This is useful if you are using a breakout board for the link cable 13 | 14 | /***************************** 15 | * SD CARD MODULE DEFINITIONS 16 | *****************************/ 17 | //Define the SD Card Module Pins 18 | #define SD_CS 15 19 | #define SD_SCK 14 20 | #define SD_MOSI 13 21 | #define SD_MISO 26 22 | 23 | /************************************ 24 | * PUSH BUTTON AND IMAGE DEFINITIONS 25 | ************************************/ 26 | #define BTN_PUSH 34 // Define a PushButton to use to Force a new file/Generate the images. 27 | //#define BTN_INVERT //Define to use the LOW state instead HIGH state. Useful for the TTGO board. 28 | #define BMP_UPSCALE_FACTOR 0 //Set the Upscale factor for the BMP output (Set 0 to disable) 29 | #define PNG_UPSCALE_FACTOR 4 //Set the Upscale factor for the PNG output (Set 0 to disable) 30 | 31 | /*************************** 32 | * OLED DISPLAY DEFINITIONS 33 | ***************************/ 34 | #define USE_OLED //Enable OLED 35 | 36 | //Uncomment this if you are using SSD1306 display driver 37 | #define USE_SSD1306 38 | #define OLED_SDA 21 39 | #define OLED_SCL 22 40 | #define OLED_COMPINS 1 // If you have some issues with the image, try to change this with values between 1 and 4 41 | 42 | //Uncomment this if you are using SSD1331 display driver 43 | //#define USE_SSD1331 44 | //#define OLED_SCLK 14 45 | //#define OLED_MOSI 13 46 | //#define OLED_MISO 12 47 | //#define OLED_CS 15 48 | //#define OLED_DC 16 49 | //#define OLED_RST 4 50 | 51 | //Set your display dimensions 52 | #define SCREEN_WIDTH 128 53 | #define SCREEN_HEIGHT 32 54 | #define OLED_ROTATE //Rotate the display by 180° 55 | 56 | /************************* 57 | * LED STATUS DEFINITIONS 58 | *************************/ 59 | // Standard LED Definitions 60 | //#define LED_STATUS_PIN 5 // LED blink on packet reception (2 is internal LED) 61 | 62 | // RGB LED Definitions 63 | #define LED_STATUS_BLUE 17 64 | #define LED_STATUS_RED 16 65 | #define LED_STATUS_GREEN 4 66 | //#define COMMON_ANODE 67 | #define COMMON_CATHODE 68 | 69 | /************************* 70 | * WEB SERVER DEFINITIONS 71 | *************************/ 72 | #define ENABLE_WEBSERVER 73 | #define WIFI_CONNECT_TIMEOUT 10000 //Connection Timeout in ms 74 | 75 | /************************* 76 | * RTC DEFINITIONS 77 | *************************/ 78 | #define ENABLE_RTC 79 | #define RTC_TIMEZONE -3 //Define your timezone 80 | #define RTC_TIMEDIFF 1080 //Define the time difference between the NTP server and the real time 81 | -------------------------------------------------------------------------------- /NeoGB_Printer/config.h presets/LilyGo TTGO-T2/config.h: -------------------------------------------------------------------------------- 1 | /********************************* 2 | * GAMEBOY LINK CABLE DEFINITIONS 3 | *********************************/ 4 | // Note: Serial Clock Pin must be attached to an interrupt pin of the arduino (Pins 1 and 4 are not used) 5 | // ___________ 6 | // | 6 4 2 | 7 | // \_5__3__1_/ (at cable) 8 | // 9 | //#define INVERT_SERIAL_PINS //Invert pin 2 and 3 order, since the pin 2 goes o 3 in the other side of the cable, and 3 goes to 2. This is useful if you are using a breakout board for the link cable 10 | #define ESP_MOSI_PIN 27 11 | #define ESP_MISO_PIN 25 12 | #define ESP_CLK_PIN 26 13 | //#define INVERT_SERIAL_PINS //Invert pin 2 and 3 order, since the pin 2 goes o 3 in the other side of the cable, and 3 goes to 2. This is useful if you are using a breakout board for the link cable 14 | 15 | /***************************** 16 | * SD CARD MODULE DEFINITIONS 17 | *****************************/ 18 | //Define the SD Card Module Pins 19 | #define SD_CS 5 20 | #define SD_SCK 18 21 | #define SD_MOSI 23 22 | #define SD_MISO 19 23 | 24 | /************************************ 25 | * PUSH BUTTON AND IMAGE DEFINITIONS 26 | ************************************/ 27 | #define BTN_PUSH 36 // Define a PushButton to use to Force a new file/Generate the images. 28 | #define BTN_INVERT //Define to use the LOW state instead HIGH state. Useful for the TTGO board. 29 | #define BMP_UPSCALE_FACTOR 0 //Set the Upsace factor for the BMP output 30 | #define PNG_UPSCALE_FACTOR 4 //Set the Upsace factor for the PNG output 31 | 32 | /*************************** 33 | * OLED DISPLAY DEFINITIONS 34 | ***************************/ 35 | #define USE_OLED //Enable OLED 36 | 37 | //Uncomment this if you are using SSD1306 display driver (I2C) 38 | //#define USE_SSD1306 39 | //#define OLED_SDA 21 40 | //#define OLED_SCL 22 41 | //#define OLED_COMPINS 1 // (If you have some issues with the image, try to change this with values between 1 and 4) 42 | 43 | //Uncomment this if you are using SSD1331 display driver (SPI) 44 | #define USE_SSD1331 45 | #define OLED_SCLK 14 46 | #define OLED_MOSI 13 47 | #define OLED_MISO 12 48 | #define OLED_CS 15 49 | #define OLED_DC 16 50 | #define OLED_RST 4 51 | 52 | //Set your display dimensions 53 | #define SCREEN_WIDTH 96 54 | #define SCREEN_HEIGHT 64 55 | #define OLED_ROTATE //Rotate the display by 180° 56 | 57 | /************************* 58 | * LED STATUS DEFINITIONS 59 | *************************/ 60 | // Standard LED Definitions 61 | //#define LED_STATUS_PIN 5 // LED blink on packet reception (2 is internal LED) 62 | 63 | // RGB LED Definitions 64 | #define LED_STATUS_BLUE 2 65 | #define LED_STATUS_RED 17 66 | #define LED_STATUS_GREEN 21 67 | //#define COMMON_ANODE 68 | //#define COMMON_CATHODE 69 | 70 | /************************* 71 | * WEB SERVER DEFINITIONS 72 | *************************/ 73 | #define ENABLE_WEBSERVER 74 | #define WIFI_CONNECT_TIMEOUT 10000 //Connection Timeout in ms 75 | 76 | /************************* 77 | * RTC DEFINITIONS 78 | *************************/ 79 | #define ENABLE_RTC 80 | #define RTC_TIMEZONE -3 //Define your timezone 81 | #define RTC_TIMEDIFF 1080 //Define the time difference between the NTP server and the real time 82 | -------------------------------------------------------------------------------- /NeoGB_Printer/config.h.txt: -------------------------------------------------------------------------------- 1 | /********************************* 2 | * GAMEBOY LINK CABLE DEFINITIONS 3 | *********************************/ 4 | // Note: Serial Clock Pin must be attached to an interrupt pin of the arduino (Pins 1 and 4 are not used) 5 | // ___________ 6 | // | 6 4 2 | 7 | // \_5__3__1_/ (at cable) 8 | // 9 | #define ESP_MOSI_PIN 23 10 | #define ESP_MISO_PIN 19 11 | #define ESP_CLK_PIN 18 12 | //#define INVERT_SERIAL_PINS //Invert pin 2 and 3 order, since the pin 2 goes o 3 in the other side of the cable, and 3 goes to 2. This is useful if you are using a breakout board for the link cable 13 | 14 | /***************************** 15 | * SD CARD MODULE DEFINITIONS 16 | *****************************/ 17 | //Define the SD Card Module Pins 18 | #define SD_CS 15 19 | #define SD_SCK 14 20 | #define SD_MOSI 13 21 | #define SD_MISO 26 22 | 23 | /************************************ 24 | * PUSH BUTTON AND IMAGE DEFINITIONS 25 | ************************************/ 26 | #define BTN_PUSH 34 // Define a PushButton to use to Force a new file/Generate the images. 27 | //#define BTN_INVERT //Define to use the LOW state instead HIGH state. Useful for the TTGO board. 28 | #define BMP_UPSCALE_FACTOR 1 //Set the Upscale factor for the BMP output (Set 0 to disable) 29 | #define PNG_UPSCALE_FACTOR 1 //Set the Upscale factor for the PNG output (Set 0 to disable) 30 | 31 | /*************************** 32 | * OLED DISPLAY DEFINITIONS 33 | ***************************/ 34 | //#define USE_OLED //Enable OLED 35 | 36 | //Uncomment this if you are using SSD1306 display driver (I2C) 37 | //#define USE_SSD1306 38 | //#define OLED_SDA 21 39 | //#define OLED_SCL 22 40 | //#define OLED_COMPINS 1 //If you have some issues with the image, try to change this with values between 1 and 4 41 | 42 | //Uncomment this if you are using SSD1331 display driver (SPI) 43 | //#define USE_SSD1331 44 | //#define OLED_SCLK 14 45 | //#define OLED_MOSI 13 46 | //#define OLED_MISO 12 47 | //#define OLED_CS 15 48 | //#define OLED_DC 16 49 | //#define OLED_RST 4 50 | 51 | //Set your display dimensions 52 | //#define SCREEN_WIDTH 128 53 | //#define SCREEN_HEIGHT 32 54 | //#define OLED_ROTATE //Rotate the display by 180° 55 | 56 | /************************* 57 | * LED STATUS DEFINITIONS 58 | *************************/ 59 | // Standard LED Definitions 60 | //#define LED_STATUS_PIN 5 // LED blink on packet reception (2 is internal LED) 61 | 62 | // RGB LED Definitions 63 | //#define LED_STATUS_BLUE 17 64 | //#define LED_STATUS_RED 16 65 | //#define LED_STATUS_GREEN 4 66 | //#define COMMON_ANODE 67 | //#define COMMON_CATHODE 68 | 69 | /************************* 70 | * WEB SERVER DEFINITIONS 71 | *************************/ 72 | //#define ENABLE_WEBSERVER 73 | #define WIFI_CONNECT_TIMEOUT 10000 //Connection Timeout in ms 74 | 75 | /************************* 76 | * RTC DEFINITIONS 77 | *************************/ 78 | #define ENABLE_RTC 79 | #define RTC_TIMEZONE -3 //Define your timezone 80 | #define RTC_TIMEDIFF 0 //Define the time difference between the NTP server and the real time -------------------------------------------------------------------------------- /NeoGB_Printer/fs_setup.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Initialize File System and SD Card 3 | *******************************************************************************/ 4 | bool fs_setup() { 5 | pinMode(SD_CS, OUTPUT); 6 | spiSD.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS); //SCK,MISO,MOSI,SS //HSPI1 7 | 8 | if (!FSYS.begin(SD_CS, spiSD)) { 9 | Serial.println("SD Card Mount Failed"); 10 | return false; 11 | }else{ 12 | uint8_t cardType = FSYS.cardType(); 13 | if(cardType == CARD_NONE){ 14 | Serial.println("No SD card attached"); 15 | return false; 16 | } 17 | 18 | Serial.printf("SD Card Size: %lluMB\n", FSYS.cardSize() / (1024 * 1024)); 19 | Serial.printf("Total space: %lluMB\n", FSYS.totalBytes() / (1024 * 1024)); 20 | Serial.printf("Used space: %lluMB\n", FSYS.usedBytes() / (1024 * 1024)); 21 | 22 | File root = FSYS.open("/dumps"); 23 | if(!root){ 24 | Serial.println("- failed to open Dumps directory"); 25 | if(FSYS.mkdir("/dumps")){ 26 | Serial.println("Dumps Dir created"); 27 | } else { 28 | Serial.println("mkdir failed"); 29 | } 30 | }else{ 31 | Serial.println("Dumps folder already exist."); 32 | } 33 | 34 | root = FSYS.open("/temp"); 35 | if(!root){ 36 | Serial.println("- failed to open Temp directory"); 37 | if(FSYS.mkdir("/temp")){ 38 | Serial.println("Temp Dir created"); 39 | } else { 40 | Serial.println("mkdir failed"); 41 | } 42 | }else{ 43 | Serial.println("Temp folder already exist."); 44 | } 45 | 46 | root = FSYS.open("/output"); 47 | if(!root){ 48 | Serial.println("- failed to open Output directory"); 49 | if(FSYS.mkdir("/output")){ 50 | Serial.println("Output Dir created"); 51 | } else { 52 | Serial.println("mkdir failed"); 53 | } 54 | }else{ 55 | Serial.println("Output folder already exist."); 56 | } 57 | 58 | root = FSYS.open("/output/bmp"); 59 | if(!root){ 60 | Serial.println("- failed to open Output BMP directory"); 61 | if(FSYS.mkdir("/output/bmp")){ 62 | Serial.println("Output BMP Dir created"); 63 | } else { 64 | Serial.println("mkdir failed"); 65 | } 66 | }else{ 67 | Serial.println("Output BMP folder already exist."); 68 | } 69 | 70 | root = FSYS.open("/output/png"); 71 | if(!root){ 72 | Serial.println("- failed to open Output PNG directory"); 73 | if(FSYS.mkdir("/output/png")){ 74 | Serial.println("Output PNG Dir created"); 75 | } else { 76 | Serial.println("mkdir failed"); 77 | } 78 | }else{ 79 | Serial.println("Output PNG folder already exist."); 80 | } 81 | 82 | root = FSYS.open("/www"); 83 | if(!root){ 84 | Serial.println("- failed to open WebServer directory"); 85 | if(FSYS.mkdir("/www")){ 86 | Serial.println("WebServer Dir created"); 87 | } else { 88 | Serial.println("mkdir failed"); 89 | } 90 | }else{ 91 | Serial.println("WebServer folder already exist."); 92 | } 93 | 94 | root = FSYS.open("/www/thumb"); 95 | if(!root){ 96 | Serial.println("- failed to open Thumbnail directory"); 97 | if(FSYS.mkdir("/www/thumb")){ 98 | Serial.println("Thumbnail Dir created"); 99 | } else { 100 | Serial.println("mkdir failed"); 101 | } 102 | }else{ 103 | Serial.println("Thumbnail folder already exist."); 104 | } 105 | 106 | for (int i = 0; i < 100; i++) { 107 | if (i % 10 == 0) { 108 | Serial.print("."); 109 | } 110 | } 111 | Serial.println(" done"); 112 | 113 | return true; 114 | } 115 | } 116 | 117 | /******************************************************************************* 118 | Get the store usage 119 | *******************************************************************************/ 120 | int fs_info() { 121 | uint64_t totalBytes=0; 122 | uint64_t usedBytes=0; 123 | totalBytes = FSYS.totalBytes(); 124 | usedBytes = FSYS.usedBytes(); 125 | 126 | return (int)( 127 | (((float)totalBytes - (float)usedBytes) / (float)totalBytes) * 100.0 128 | ); 129 | } 130 | 131 | /******************************************************************************* 132 | Get the number of images and dumps to show 133 | *******************************************************************************/ 134 | #ifdef USE_OLED 135 | void GetNumberFiles() { 136 | int totalDumps=get_dumps(); 137 | oled_writeNumImages(totalDumps); 138 | } 139 | #endif 140 | 141 | /******************************************************************************* 142 | "Printer Full" function 143 | *******************************************************************************/ 144 | void full() { 145 | Serial.println("no more space on printer"); 146 | #ifdef LED_STATUS_PIN 147 | LED_led_ON(LED_STATUS_PIN); 148 | #endif 149 | #if defined(COMMON_ANODE) || defined(COMMON_CATHODE) 150 | LED_led_ON(LED_STATUS_RED); 151 | #endif 152 | #ifdef USE_OLED 153 | oledStateChange(3); //Printer Full 154 | #endif 155 | } 156 | 157 | /******************************************************************************* 158 | Simple controller to change the Boot Mode 159 | *******************************************************************************/ 160 | bool fs_alternateBootMode() { 161 | char path[]="/bootmode.txt"; 162 | 163 | if(FSYS.remove(path)){ 164 | return false; 165 | } else { 166 | File file = FSYS.open(path,FILE_WRITE); 167 | file.print("BOOT"); 168 | file.close(); 169 | return true; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /NeoGB_Printer/gbp_pkt.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * 3 | * Gameboy Printer Packet Parser 4 | * Part of GAMEBOY PRINTER EMULATION PROJECT V2 (Arduino) 5 | * Copyright (C) 2020 Brian Khuu 6 | * 7 | * PURPOSE: This module focus on parsing a stream of bytes as gbp packets 8 | * LICENCE: 9 | * This file is part of Arduino Gameboy Printer Emulator. 10 | * 11 | * Arduino Gameboy Printer Emulator is free software: 12 | * you can redistribute it and/or modify it under the terms of the 13 | * GNU General Public License as published by the Free Software Foundation, 14 | * either version 3 of the License, or (at your option) any later version. 15 | * 16 | * Arduino Gameboy Printer Emulator is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with Arduino Gameboy Printer Emulator. If not, see . 23 | */ 24 | 25 | #include 26 | #include 27 | 28 | #include "./includes/gblink/gameboy_printer_protocol.h" 29 | #include "./includes/gblink/gbp_serial_io.h" 30 | #include "./includes/gblink/gbp_pkt.h" 31 | 32 | bool gbp_pkt_init(gbp_pkt_t *_pkt) 33 | { 34 | _pkt->pktByteIndex = 0; 35 | _pkt->buffIndex = 0; 36 | return true; 37 | } 38 | 39 | bool gbp_pkt_reset(gbp_pkt_t *_pkt) 40 | { 41 | _pkt->pktByteIndex = 0; 42 | _pkt->buffIndex = 0; 43 | return true; 44 | } 45 | 46 | // returns true if packet is received 47 | bool gbp_pkt_processByte(gbp_pkt_t *_pkt, const uint8_t _byte, uint8_t buffer[], uint8_t *bufferSize, const size_t bufferMax) 48 | { 49 | /* 50 | [ 00 ][ 01 ][ 02 ][ 03 ][ 04 ][ 05 ][ 5+X ][5+X+1][5+X+2][5+X+3][5+X+4] 51 | [SYNC][SYNC][COMM][COMP][LEN0][LEN1][DATAX][CSUM0][CSUM1][DUMMY][DUMMY] 52 | */ 53 | 54 | // Dev Note: Minimum required size of 4 bytes for printer instruction packet 55 | // data payload can be streamed so doesn't have to fit full size 56 | if (bufferMax < 4) 57 | return false; 58 | 59 | _pkt->received = GBP_REC_NONE; 60 | 61 | // Parsing fixed packet header 62 | if (_pkt->pktByteIndex <= 5) 63 | { 64 | if (_pkt->pktByteIndex == 1) 65 | { 66 | _pkt->command = 0; 67 | _pkt->compression = 0; 68 | _pkt->dataLength = 0; 69 | _pkt->printerID = 0; 70 | _pkt->status = 0; 71 | *bufferSize = 0; 72 | } 73 | 74 | switch (_pkt->pktByteIndex) 75 | { 76 | case 0: _pkt->pktByteIndex = (_byte == 0x88) ? 1 : 0; break; 77 | case 1: _pkt->pktByteIndex = (_byte == 0x33) ? 2 : 0; break; 78 | case 2: _pkt->pktByteIndex++; _pkt->command = _byte; break; 79 | case 3: _pkt->pktByteIndex++; _pkt->compression = _byte; break; 80 | case 4: _pkt->pktByteIndex++; _pkt->dataLength = ((uint16_t)_byte << 0) & 0x00FF; break; 81 | case 5: _pkt->pktByteIndex++; _pkt->dataLength |= ((uint16_t)_byte << 8) & 0xFF00; break; 82 | default: break; 83 | } 84 | 85 | // Data packets are streamed 86 | if (_pkt->pktByteIndex == 6) 87 | { 88 | if (bufferMax > _pkt->dataLength) 89 | { 90 | // Payload fits into buffer 91 | return false; 92 | } 93 | else 94 | { 95 | // Must stream... 96 | _pkt->received = GBP_REC_GOT_PACKET; 97 | return true; 98 | } 99 | } 100 | 101 | return false; 102 | } 103 | 104 | // Capture Bytes to buffer if needed 105 | if ((6 <= _pkt->pktByteIndex) && (_pkt->pktByteIndex < (6 + _pkt->dataLength))) 106 | { 107 | // Byte is from payload... add to buffer 108 | const uint16_t payloadIndex = _pkt->pktByteIndex - 6; 109 | //const uint16_t offset = (payloadIndex/bufferMax) * bufferMax; 110 | const uint16_t bufferUsage = payloadIndex % bufferMax + 1; 111 | buffer[bufferUsage - 1] = _byte; 112 | *bufferSize = bufferUsage; 113 | if (bufferUsage == _pkt->dataLength) 114 | { 115 | // Fits fully in buffer 116 | } 117 | else if (bufferUsage == bufferMax) 118 | { 119 | _pkt->received = GBP_REC_GOT_PAYLOAD_PARTAL; 120 | } 121 | } 122 | else if (_pkt->pktByteIndex == (6 + _pkt->dataLength)) 123 | { 124 | *bufferSize = _pkt->dataLength % bufferMax; 125 | } 126 | 127 | // Increment 128 | if (_pkt->pktByteIndex == (8 + _pkt->dataLength)) 129 | { 130 | _pkt->printerID = _byte; 131 | } 132 | else if (_pkt->pktByteIndex == (8 + _pkt->dataLength + 1)) 133 | { 134 | // End of packet reached 135 | _pkt->status = _byte; 136 | _pkt->pktByteIndex = 0; 137 | // Indicate received packet 138 | if (bufferMax > _pkt->dataLength) 139 | { 140 | // Payload fits into buffer 141 | _pkt->received = GBP_REC_GOT_PACKET; 142 | return true; 143 | } 144 | else 145 | { 146 | // Finished streaming 147 | _pkt->received = GBP_REC_GOT_PACKET_END; 148 | return true; 149 | } 150 | } 151 | 152 | _pkt->pktByteIndex++; 153 | return _pkt->received != GBP_REC_NONE; 154 | } 155 | 156 | 157 | /******************************************************************************* 158 | Tile Accumulator 159 | *******************************************************************************/ 160 | 161 | static bool gbp_pkt_tileAccu_insertByte(gbp_pkt_tileAcc_t *tileBuff, const uint8_t byte) 162 | { 163 | if (tileBuff->count == GBP_TILE_SIZE_IN_BYTE) 164 | return true; 165 | 166 | tileBuff->tile[tileBuff->count] = byte; 167 | tileBuff->count++; 168 | return tileBuff->count == GBP_TILE_SIZE_IN_BYTE; 169 | } 170 | 171 | bool gbp_pkt_tileAccu_tileReadyCheck(gbp_pkt_tileAcc_t *tileBuff) 172 | { 173 | if (tileBuff->count < GBP_TILE_SIZE_IN_BYTE) 174 | return false; 175 | 176 | tileBuff->count = 0; 177 | return true; 178 | } 179 | 180 | 181 | /******************************************************************************* 182 | *******************************************************************************/ 183 | 184 | bool gbp_pkt_decompressor(gbp_pkt_t *_pkt, const uint8_t buff[], const size_t buffSize, gbp_pkt_tileAcc_t *tileBuff) 185 | { 186 | if (!_pkt->compression) 187 | { 188 | // Uncompressed payload // e.g. Gameboy Camera 189 | while (1) 190 | { 191 | // for (buffIndex = 0; buffIndex < buffSize ; buffIndex++) 192 | if (_pkt->buffIndex < buffSize) 193 | { 194 | if (gbp_pkt_tileAccu_insertByte(tileBuff, buff[_pkt->buffIndex++])) 195 | { 196 | return true; // Got tile 197 | } 198 | } 199 | else 200 | { 201 | _pkt->buffIndex = 0; // Reset for next buffer 202 | return false; 203 | } 204 | } 205 | } 206 | else 207 | { 208 | // Compressed payload (Run length encoding) // e.g. Pokemon Trading Card 209 | while (1) 210 | { 211 | // for (buffIndex = 0; buffIndex < buffSize ; buffIndex++) 212 | // Dev Note: Need to also check if we have completed adding looped byte even if all incoming bytes have been read 213 | if ((_pkt->buffIndex < buffSize) || (_pkt->compressedRun && !_pkt->repeatByteGet && (_pkt->loopRunLength != 0))) 214 | { 215 | // Incoming Bytes Avaliable 216 | if (_pkt->loopRunLength == 0) 217 | { 218 | // Start of either a raw run of byte or compressed run of byte 219 | uint8_t b = buff[_pkt->buffIndex++]; 220 | if (b < 128) 221 | { 222 | // (0x7F=127) its a classical run, read the n bytes after (Raphael-Boichot) 223 | _pkt->loopRunLength = b + 1; 224 | _pkt->compressedRun = false; 225 | } 226 | else if (b >= 128) 227 | { 228 | // (0x80 = 128) its a compressed run, read the next byte and repeat (Raphael-Boichot) 229 | _pkt->loopRunLength = b - 128 + 2; 230 | _pkt->compressedRun = true; 231 | _pkt->repeatByteGet = true; 232 | } 233 | } 234 | else if (_pkt->repeatByteGet) 235 | { 236 | // Grab loop byte 237 | uint8_t b = buff[_pkt->buffIndex++]; 238 | _pkt->repeatByte = b; 239 | _pkt->repeatByteGet = false; 240 | } 241 | else 242 | { 243 | const uint8_t b = (_pkt->compressedRun) ? _pkt->repeatByte : buff[_pkt->buffIndex++]; 244 | _pkt->loopRunLength--; 245 | if (gbp_pkt_tileAccu_insertByte(tileBuff, b)) 246 | { 247 | return true; // Got tile 248 | } 249 | } 250 | } 251 | else 252 | { 253 | _pkt->buffIndex = 0; // Reset for next buffer 254 | return false; 255 | } 256 | } 257 | } 258 | return false; 259 | } 260 | -------------------------------------------------------------------------------- /NeoGB_Printer/gbp_tiles.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * 3 | * Gameboy Printer Tile Decoder 4 | * Part of GAMEBOY PRINTER EMULATION PROJECT V2 (Arduino) 5 | * Copyright (C) 2020 Brian Khuu 6 | * 7 | * PURPOSE: This module focus on decoder gameboy printer tiles to bmp 8 | * LICENCE: 9 | * This file is part of Arduino Gameboy Printer Emulator. 10 | * 11 | * Arduino Gameboy Printer Emulator is free software: 12 | * you can redistribute it and/or modify it under the terms of the 13 | * GNU General Public License as published by the Free Software Foundation, 14 | * either version 3 of the License, or (at your option) any later version. 15 | * 16 | * Arduino Gameboy Printer Emulator is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with Arduino Gameboy Printer Emulator. If not, see . 23 | */ 24 | 25 | #include // uint8_t 26 | #include // size_t 27 | #include // bool 28 | 29 | #include "./includes/gblink/gameboy_printer_protocol.h" 30 | #include "./includes/gblink/gbp_tiles.h" 31 | 32 | static void gbp_tiles_toBuff( 33 | uint8_t *buff, 34 | const int buffSize, 35 | const int buffTileCount, 36 | const int tileLineOffset, 37 | const int tileRowOffset, 38 | const uint8_t tileBuff[GBP_TILE_SIZE_IN_BYTE]) 39 | { 40 | // This converts tile data to a bitmap buffer 41 | // The bitmap buffer has enough space to contain multiple decoded tiles 42 | // And each area is written to by x tile offset 43 | 44 | // Guard 45 | if (buffSize < (buffTileCount * GBP_TILE_PIXEL_HEIGHT * GBP_TILE_2BIT_LINEPACK_ROWSIZE_B(GBP_TILE_PIXEL_WIDTH))) 46 | return; 47 | 48 | const int lineWidthSize = GBP_TILE_2BIT_LINEPACK_ROWSIZE_B(buffTileCount * GBP_TILE_PIXEL_WIDTH); 49 | const int rowHeightSize = lineWidthSize * GBP_TILE_PIXEL_HEIGHT; 50 | 51 | // Tile Decoder 52 | for (int j = 0; j < GBP_TILE_PIXEL_HEIGHT; j++) 53 | { 54 | for (int i = 0; i < GBP_TILE_PIXEL_WIDTH; i++) 55 | { 56 | const int offset = tileLineOffset * GBP_TILE_2BIT_LINEPACK_ROWSIZE_B(GBP_TILE_PIXEL_WIDTH); 57 | const uint8_t hiBit = (uint8_t)((tileBuff[j*2 + 1] >> (7 - i)) & 1); 58 | const uint8_t loBit = (uint8_t)((tileBuff[j*2 ] >> (7 - i)) & 1); 59 | const uint8_t value = (uint8_t)((hiBit << 1) | loBit); // 0-3 60 | const unsigned int indx = (tileRowOffset * rowHeightSize) + (j * lineWidthSize) + offset + GBP_TILE_2BIT_LINEPACK_INDEX(i); 61 | buff[indx] &= ~(0b11 << GBP_TILE_2BIT_LINEPACK_BITOFFSET(i)); 62 | buff[indx] |= value << GBP_TILE_2BIT_LINEPACK_BITOFFSET(i); 63 | } 64 | } 65 | } 66 | 67 | bool gbp_tiles_line_decoder(gbp_tile_t *gbp_tiles, const uint8_t tileBuff[GBP_TILE_SIZE_IN_BYTE]) 68 | { 69 | gbp_tiles_toBuff( 70 | (uint8_t *)gbp_tiles->bmpLineBuffer, 71 | GBP_TILE_PIXEL_HEIGHT * GBP_TILE_PIXEL_WIDTH * GBP_TILES_PER_LINE, 72 | GBP_TILES_PER_LINE, 73 | gbp_tiles->tileLineOffset, 74 | gbp_tiles->tileRowOffset, 75 | tileBuff); 76 | gbp_tiles->tileLineOffset++; 77 | if (gbp_tiles->tileLineOffset >= GBP_TILES_PER_LINE) 78 | { 79 | // Enough tiles decoded to output a fully decoded line 80 | gbp_tiles->tileLineOffset = 0; 81 | gbp_tiles->tileRowOffset++; 82 | return true; 83 | } 84 | 85 | // Tile Decoded, but not enough to make a line 86 | return false; 87 | } 88 | 89 | /*****************************************************************************/ 90 | 91 | void gbp_tiles_reset(gbp_tile_t *gbp_tiles) 92 | { 93 | (void)gbp_tiles; 94 | gbp_tiles->tileLineOffset = 0; 95 | gbp_tiles->tileRowOffset = 0; 96 | gbp_tiles->tileRowOffsetHarmonised = 0; 97 | } 98 | 99 | void gbp_tiles_print(gbp_tile_t *gbp_tiles, uint8_t sheet, uint8_t linefeed, uint8_t pallet, uint8_t density) 100 | { 101 | (void)gbp_tiles; 102 | (void)sheet; 103 | (void)linefeed; 104 | (void)pallet; 105 | (void)density; 106 | 107 | /* Harmonise Pallete */ 108 | // Ref: https://github.com/Raphael-Boichot/The-Arduino-SD-Game-Boy-Printer#some-technical-facts 109 | // Palette 0x00 has the same effect than palette 0xE4 (the mainly encountered palette in games) 110 | uint8_t tonePallet[GBP_TILE_MAX_TONES] = {0}; 111 | pallet = (pallet == 0x00) ? 0xE4 : pallet; 112 | tonePallet[0] = ((pallet >> 0) & 0b11); 113 | tonePallet[1] = ((pallet >> 2) & 0b11); 114 | tonePallet[2] = ((pallet >> 4) & 0b11); 115 | tonePallet[3] = ((pallet >> 6) & 0b11); 116 | const int startH = GBP_TILE_PIXEL_HEIGHT * gbp_tiles->tileRowOffsetHarmonised; 117 | const int endH = GBP_TILE_PIXEL_HEIGHT * gbp_tiles->tileRowOffset; 118 | 119 | if (startH > endH) 120 | return; 121 | 122 | for (int j = startH; j < endH; j++) 123 | { 124 | for (int i = 0; i < GBP_TILE_PIXEL_WIDTH * GBP_TILES_PER_LINE; i++) 125 | { 126 | const uint8_t pixel = 0b11 & (gbp_tiles->bmpLineBuffer[j][GBP_TILE_2BIT_LINEPACK_INDEX(i)] >> GBP_TILE_2BIT_LINEPACK_BITOFFSET(i)); 127 | const uint8_t harmonised = tonePallet[pixel & 0b11]; 128 | gbp_tiles->bmpLineBuffer[j][GBP_TILE_2BIT_LINEPACK_INDEX(i)] &= ~(0b11 << GBP_TILE_2BIT_LINEPACK_BITOFFSET(i)); 129 | gbp_tiles->bmpLineBuffer[j][GBP_TILE_2BIT_LINEPACK_INDEX(i)] |= (harmonised << GBP_TILE_2BIT_LINEPACK_BITOFFSET(i)); 130 | } 131 | } 132 | gbp_tiles->tileRowOffsetHarmonised = gbp_tiles->tileRowOffset; 133 | } 134 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/StoreIDlib.h: -------------------------------------------------------------------------------- 1 | 2 | #include "Arduino.h" 3 | //SD libraries 4 | #include "FS.h" 5 | #include "SD.h" 6 | #include "SPI.h" 7 | #define FSYS SD 8 | 9 | /////////////////////////////////////////////////////////////////////////////////////create the ID file//////////////// 10 | void ID_file_checker() { 11 | uint8_t buf[4]; 12 | char path[]="/ID_storage.bin"; 13 | if(FSYS.exists(path)){ 14 | //skip the step 15 | Serial.println("Configuration file already on SD card"); 16 | return; 17 | } else { 18 | File file = FSYS.open(path,FILE_WRITE); 19 | //start from a fresh install on SD 20 | unsigned long ID=1; 21 | buf[3] = ID >> 0; 22 | buf[2] = ID >> 8; 23 | buf[1] = ID >> 16; 24 | buf[0] = ID >> 24; 25 | file.write(buf, 4); 26 | 27 | unsigned long dumps=0; 28 | buf[3] = dumps >> 0; 29 | buf[2] = dumps >> 8; 30 | buf[1] = dumps >> 16; 31 | buf[0] = dumps >> 24; 32 | file.write(buf, 4); 33 | 34 | // unsigned long total_images=0; 35 | // buf[3] = total_images >> 0; 36 | // buf[2] = total_images >> 8; 37 | // buf[1] = total_images >> 16; 38 | // buf[0] = total_images >> 24; 39 | // file.write(buf, 4); 40 | // file.close(); 41 | Serial.println("Fresh configuration file created on SD card"); 42 | } 43 | } 44 | ////////////////////////////////////////////////////////////////////////////////////create the ID file//////////////// 45 | 46 | /////////////////////////////////////////////////////////////////////////////////////Get the next ID//////////////// 47 | unsigned long get_next_ID() { 48 | uint8_t buf[8]; 49 | char path[]="/ID_storage.bin"; 50 | File file = FSYS.open(path); 51 | file.read(buf, 8); 52 | unsigned long Next_ID = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3])); 53 | file.close(); 54 | Serial.printf("Next Image: %05d\n",Next_ID); 55 | return Next_ID; 56 | } 57 | /////////////////////////////////////////////////////////////////////////////////////Get the next ID//////////////// 58 | 59 | ////////////////////////////////////////////////////////////////////////////////////Get the dumps number//////////////// 60 | unsigned long get_dumps() { 61 | uint8_t buf[8]; 62 | char path[]="/ID_storage.bin"; 63 | File file = FSYS.open(path); 64 | file.read(buf, 8); 65 | unsigned long dumps = ((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | (buf[7])); 66 | file.close(); 67 | return dumps; 68 | } 69 | /////////////////////////////////////////////////////////////////////////////////////Get the dumps number//////////////// 70 | 71 | ////////////////////////////////////////////////////////////////////////////////////Get the total image number//////////////// 72 | //unsigned long get_images() { 73 | // uint8_t buf[12]; 74 | // char path[]="/ID_storage.bin"; 75 | // File file = FSYS.open(path); 76 | // file.read(buf, 12); 77 | // unsigned long images = ((buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | (buf[11])); 78 | // file.close(); 79 | // return images; 80 | //} 81 | /////////////////////////////////////////////////////////////////////////////////////Get the total image number//////////////// 82 | 83 | /////////////////////////////////////////////////////////////////////////////////////update the next ID//////////////// 84 | void update_next_ID(int mod) { 85 | uint8_t buf[8]; 86 | char path[]="/ID_storage.bin"; 87 | File file = FSYS.open(path); 88 | file.read(buf, 8); 89 | unsigned long Next_ID = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3])); 90 | Next_ID=Next_ID+mod; 91 | if (Next_ID>99999) Next_ID=1; 92 | file.close(); 93 | buf[3] = Next_ID >> 0; 94 | buf[2] = Next_ID >> 8; 95 | buf[1] = Next_ID >> 16; 96 | buf[0] = Next_ID >> 24; 97 | file = FSYS.open(path,FILE_WRITE); 98 | file.write(buf, 8); 99 | file.close(); 100 | } 101 | unsigned long update_get_next_ID(int mod) { 102 | uint8_t buf[8]; 103 | char path[]="/ID_storage.bin"; 104 | File file = FSYS.open(path); 105 | file.read(buf, 8); 106 | unsigned long Next_ID = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3])); 107 | Next_ID=Next_ID+mod; 108 | if (Next_ID>99999) Next_ID=1; 109 | file.close(); 110 | buf[3] = Next_ID >> 0; 111 | buf[2] = Next_ID >> 8; 112 | buf[1] = Next_ID >> 16; 113 | buf[0] = Next_ID >> 24; 114 | file = FSYS.open(path,FILE_WRITE); 115 | file.write(buf, 8); 116 | file.close(); 117 | Serial.printf("Next Image: %05d\n",Next_ID); 118 | return Next_ID; 119 | } 120 | /////////////////////////////////////////////////////////////////////////////////////update the next ID//////////////// 121 | 122 | /////////////////////////////////////////////////////////////////////////////////////update the dumps//////////////// 123 | void update_dumps(int mod) { 124 | uint8_t buf[8]; 125 | char path[]="/ID_storage.bin"; 126 | File file = FSYS.open(path); 127 | file.read(buf, 8); 128 | unsigned long dumps = ((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | (buf[7])); 129 | dumps=dumps+mod; 130 | file.close(); 131 | buf[7] = dumps >> 0; 132 | buf[6] = dumps >> 8; 133 | buf[5] = dumps >> 16; 134 | buf[4] = dumps >> 24; 135 | file = FSYS.open(path,FILE_WRITE); 136 | file.write(buf, 8); 137 | file.close(); 138 | } 139 | unsigned long update_get_dumps(int mod) { 140 | uint8_t buf[8]; 141 | char path[]="/ID_storage.bin"; 142 | File file = FSYS.open(path); 143 | file.read(buf, 8); 144 | unsigned long dumps = ((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | (buf[7])); 145 | dumps=dumps+mod; 146 | file.close(); 147 | buf[7] = dumps >> 0; 148 | buf[6] = dumps >> 8; 149 | buf[5] = dumps >> 16; 150 | buf[4] = dumps >> 24; 151 | file = FSYS.open(path,FILE_WRITE); 152 | file.write(buf, 8); 153 | file.close(); 154 | return dumps; 155 | } 156 | void set_dumps(long dumps) { 157 | uint8_t buf[8]; 158 | char path[]="/ID_storage.bin"; 159 | File file = FSYS.open(path); 160 | file.read(buf, 8); 161 | file.close(); 162 | buf[7] = dumps >> 0; 163 | buf[6] = dumps >> 8; 164 | buf[5] = dumps >> 16; 165 | buf[4] = dumps >> 24; 166 | file = FSYS.open(path,FILE_WRITE); 167 | file.write(buf, 8); 168 | file.close(); 169 | } 170 | /////////////////////////////////////////////////////////////////////////////////////update the dumps//////////////// 171 | 172 | /////////////////////////////////////////////////////////////////////////////////////update the total images//////////////// 173 | //void update_images(int mod) { 174 | // uint8_t buf[12]; 175 | // char path[]="/ID_storage.bin"; 176 | // File file = FSYS.open(path); 177 | // file.read(buf, 12); 178 | // unsigned long images = ((buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | (buf[11])); 179 | // images=images+mod; 180 | // file.close(); 181 | // buf[11] = images >> 0; 182 | // buf[10] = images >> 8; 183 | // buf[9] = images >> 16; 184 | // buf[8] = images >> 24; 185 | // file = FSYS.open(path,FILE_WRITE); 186 | // file.write(buf, 12); 187 | // file.close(); 188 | //} 189 | //unsigned long update_get_images(int mod) { 190 | // uint8_t buf[12]; 191 | // char path[]="/ID_storage.bin"; 192 | // File file = FSYS.open(path); 193 | // file.read(buf, 12); 194 | // unsigned long images = ((buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | (buf[11])); 195 | // images=images+mod; 196 | // file.close(); 197 | // buf[11] = images >> 0; 198 | // buf[10] = images >> 8; 199 | // buf[9] = images >> 16; 200 | // buf[8] = images >> 24; 201 | // file = FSYS.open(path,FILE_WRITE); 202 | // file.write(buf, 12); 203 | // file.close(); 204 | // return images; 205 | //} 206 | /////////////////////////////////////////////////////////////////////////////////////update the total images//////////////// 207 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/display/SSD1306.hpp: -------------------------------------------------------------------------------- 1 | #define LGFX_USE_V1 // v1.0.0 を有効にします(v0からの移行期間の特別措置とのこと。書かない場合は旧v0系で動作) 2 | #include // lovyanGFXのヘッダを準備 3 | 4 | // 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。 5 | // クラス名はLGFXからLGFX_SSD1306に変更してます。(コンストラクタ名も) 6 | class LGFX_SSD1306 : public lgfx::LGFX_Device { 7 | // 接続するOLED表示器にあったインスタンスを準備します。 8 | lgfx::Panel_SSD1306 _panel_instance; // SSD1306を使用する場合 9 | lgfx::Bus_I2C _bus_instance; // I2Cバスのインスタンス (ESP32のみ) 10 | 11 | // コンストラクタを作成し、ここで各種設定を行います。 12 | public: 13 | LGFX_SSD1306(void) { // コンストラクタ名はクラス名に合わせてLGFXからLGFX_SSD1306に変更してます。(クラス名と同じにする) 14 | { // バス制御の設定を行います。 15 | auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。 16 | // I2Cバスの設定 17 | cfg.i2c_port = 0; // 使用するI2Cポートを選択 (0 or 1) 18 | cfg.freq_write = 400000; // 送信時のクロック 19 | cfg.freq_read = 400000; // 受信時のクロック 20 | cfg.pin_sda = OLED_SDA; // SDAを接続しているピン番号 21 | cfg.pin_scl = OLED_SCL; // SCLを接続しているピン番号 22 | cfg.i2c_addr = 0x3C; // I2Cデバイスのアドレス 23 | 24 | _bus_instance.config(cfg); // 設定値をバスに反映します。 25 | _panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。 26 | } 27 | 28 | { // 表示パネル制御の設定を行います。 29 | auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。 30 | 31 | cfg.pin_cs = -1; // CSが接続されているピン番号 (-1 = disable) 32 | cfg.pin_rst = -1; // RSTが接続されているピン番号 (-1 = disable) 33 | cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable) 34 | 35 | // ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。 36 | 37 | cfg.panel_width = SCREEN_WIDTH; // 実際に表示可能な幅 38 | cfg.panel_height = SCREEN_HEIGHT; // 実際に表示可能な高さ 39 | cfg.offset_x = 0; // パネルのX方向オフセット量 40 | cfg.offset_y = 0; // パネルのY方向オフセット量 41 | cfg.offset_rotation = 2; // 回転方向の値のオフセット 0~7 (4~7は上下反転) 42 | // cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数 43 | // cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数 44 | // cfg.readable = false; // データ読出しが可能な場合 trueに設定 45 | cfg.invert = false; // パネルの明暗が反転してしまう場合 trueに設定 46 | // cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定 47 | // cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定 48 | // cfg.bus_shared = true; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います) 49 | 50 | // 以下はST7735やILI9163のようにピクセル数が可変のドライバで表示がずれる場合にのみ設定してください。 51 | // cfg.memory_width = SCREEN_WIDTH; // ドライバICがサポートしている最大の幅 52 | // cfg.memory_height = SCREEN_HEIGHT; // ドライバICがサポートしている最大の高さ 53 | 54 | _panel_instance.config(cfg); 55 | switch (OLED_COMPINS) { 56 | case 1: 57 | _panel_instance.setComPins(0x02); 58 | break; 59 | case 2: 60 | _panel_instance.setComPins(0x12); 61 | break; 62 | case 3: 63 | _panel_instance.setComPins(0x22); 64 | break; 65 | case 4: 66 | _panel_instance.setComPins(0x32); 67 | break; 68 | default: 69 | _panel_instance.setComPins(0x02); 70 | } 71 | 72 | } 73 | setPanel(&_panel_instance); // 使用するパネルをセットします。 74 | } 75 | }; -------------------------------------------------------------------------------- /NeoGB_Printer/includes/display/SSD1331.hpp: -------------------------------------------------------------------------------- 1 | #define LGFX_USE_V1 // v1.0.0 を有効にします(v0からの移行期間の特別措置とのこと。書かない場合は旧v0系で動作) 2 | #include // lovyanGFXのヘッダを準備 3 | 4 | // 独自の設定を行うクラスを、LGFX_Deviceから派生して作成します。 5 | // クラス名はLGFXからLGFX_SSD1306に変更してます。(コンストラクタ名も) 6 | class LGFX_SSD1331 : public lgfx::LGFX_Device { 7 | // 接続するOLED表示器にあったインスタンスを準備します。 8 | lgfx::Panel_SSD1331 _panel_instance; // SSD1306を使用する場合 9 | lgfx::Bus_SPI _bus_instance; // I2Cバスのインスタンス (ESP32のみ) 10 | 11 | // コンストラクタを作成し、ここで各種設定を行います。 12 | public: 13 | LGFX_SSD1331() { // コンストラクタ名はクラス名に合わせてLGFXからLGFX_SSD1306に変更してます。(クラス名と同じにする) 14 | { // バス制御の設定を行います。 15 | // Set the bus control. 16 | auto cfg = _bus_instance.config (); // Get the structure for bus configuration. 17 | 18 | // SPI bus settings 19 | cfg.spi_host = HSPI_HOST; // Select the SPI to use ESP32-S2, C3: SPI2_HOST or SPI3_HOST / ESP32: VSPI_HOST or HSPI_HOST 20 | // * With the ESP-IDF version upgrade, the description of VSPI_HOST and HSPI_HOST is deprecated, so if an error occurs, use SPI2_HOST, SPI3_HOST instead. 21 | cfg.spi_mode = 0; // Set SPI communication mode (0 ~ 3) 22 | cfg.freq_write = 40000000; // SPI clock at the time of transmission (up to 80MHz, rounded to 80MHz divided by an integer) 23 | cfg.freq_read = 16000000; // SPI clock on reception 24 | cfg.spi_3wire = true; // Set true when receiving with MOSI pin 25 | cfg.use_lock = true; // Set true if transaction lock is used 26 | cfg.dma_channel = SPI_DMA_CH_AUTO; // Set the DMA channel to use (0 = DMA not used / 1 = 1ch / 2 = ch / SPI_DMA_CH_AUTO = automatic setting) 27 | // * With the ESP-IDF version upgrade, SPI_DMA_CH_AUTO (automatic setting) is recommended for the DMA channel. Specifying 1ch and 2ch is deprecated. 28 | cfg.pin_sclk = OLED_SCLK; // Set the SPI SCLK pin number 29 | cfg.pin_mosi = OLED_MOSI; // Set the SPI MOSI pin number 30 | cfg.pin_miso = OLED_MISO; // Set the SPI MISO pin number (-1 = disable) 31 | cfg.pin_dc = OLED_DC; // Set SPI D / C pin number (-1 = disable) 32 | 33 | _bus_instance.config (cfg); // Reflect the setting value on the bus. 34 | _panel_instance.setBus (& _bus_instance); // Set the bus to the panel. 35 | } 36 | { // 表示パネル制御の設定を行います。 37 | auto cfg = _panel_instance.config (); // Get the structure for display panel settings. 38 | 39 | cfg.pin_cs = OLED_CS; // Pin number to which CS is connected (-1 = disable) 40 | cfg.pin_rst = OLED_RST; // Pin number to which RST is connected (-1 = disable) 41 | cfg.pin_busy = -1; // Pin number to which BUSY is connected (-1 = disable) 42 | 43 | cfg.memory_width = SCREEN_WIDTH; // Maximum width supported by driver IC 44 | cfg.memory_height = SCREEN_HEIGHT; // Maximum height supported by driver IC 45 | //cfg.panel_width = 96; // Actually displayable width 46 | //cfg.panel_height = 64; // Height that can actually be displayed 47 | cfg.offset_x = 0; // Amount of offset in the X direction of the panel 48 | cfg.offset_y = 0; // Amount of offset in the Y direction of the panel 49 | cfg.offset_rotation = 2; // Offset of the value in the rotation direction 0 ~ 7 (4 ~ 7 is upside down) 50 | //cfg.dummy_read_pixel = 8; // Number of dummy read bits before pixel read 51 | //cfg.dummy_read_bits = 1; // Number of bits of dummy read before reading data other than pixels 52 | cfg.readable = false; // Set to true if data can be read 53 | //cfg.invert = false; // Set to true if the light and darkness of the panel is reversed 54 | //cfg.rgb_order = false; // Set to true if the red and blue of the panel are swapped 55 | //cfg.dlen_16bit = false; // Set to true for panels that send data length in 16-bit units 56 | //cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control is performed with drawJpgFile etc.) 57 | 58 | _panel_instance.config (cfg); 59 | } 60 | setPanel(&_panel_instance); // 使用するパネルをセットします。 61 | } 62 | }; -------------------------------------------------------------------------------- /NeoGB_Printer/includes/gblink/gbp_cbuff.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * 3 | * GAMEBOY PRINTER EMULATION PROJECT V2 (Arduino) 4 | * Copyright (C) 2020 Brian Khuu 5 | * 6 | * PURPOSE: Simple Circular Buffer for passing captured bytes for packet parser 7 | * LICENCE: 8 | * This file is part of Arduino Gameboy Printer Emulator. 9 | * 10 | * Arduino Gameboy Printer Emulator is free software: 11 | * you can redistribute it and/or modify it under the terms of the 12 | * GNU General Public License as published by the Free Software Foundation, 13 | * either version 3 of the License, or (at your option) any later version. 14 | * 15 | * Arduino Gameboy Printer Emulator is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with Arduino Gameboy Printer Emulator. If not, see . 22 | * 23 | */ 24 | 25 | 26 | #ifndef GBP_CBUFF_H 27 | #define GBP_CBUFF_H 28 | /******************************************************************************/ 29 | // # Circular Byte Buffer For Embedded Applications (Index Based) 30 | // Author: Brian Khuu (July 2020) (briankhuu.com) (mofosyne@gmail.com) 31 | // This Gist (Pointer): https://gist.github.com/mofosyne/d7a4a8d6a567133561c18aaddfd82e6f 32 | // This Gist (Index): https://gist.github.com/mofosyne/82020d5c0e1e11af0eb9b05c73734956 33 | #include // uint8_t 34 | #include // size_t 35 | #include // bool 36 | 37 | typedef struct gpb_cbuff_t 38 | { 39 | size_t capacity; ///< Maximum number of items in the buffer 40 | size_t count; ///< Number of items in the buffer 41 | uint8_t *buffer; ///< Data Buffer 42 | size_t head; ///< Head Index 43 | size_t tail; ///< Tail Index 44 | 45 | #ifdef FEATURE_CHECKSUM_SUPPORTED 46 | // Temp 47 | size_t countTemp; ///< Number of items in the buffer 48 | size_t headTemp; ///< Head Index 49 | #endif // FEATURE_CHECKSUM_SUPPORTED 50 | } gpb_cbuff_t; 51 | 52 | static inline bool gpb_cbuff_Init(gpb_cbuff_t *cb, size_t capacity, uint8_t *buffPtr) 53 | { 54 | gpb_cbuff_t emptyCB = {0}; 55 | if ((cb == NULL) || (buffPtr == NULL)) 56 | return false; ///< Failed 57 | // Init Struct 58 | *cb = emptyCB; 59 | cb->capacity = capacity; 60 | cb->buffer = buffPtr; 61 | cb->count = 0; 62 | cb->head = 0; 63 | cb->tail = 0; 64 | return true; ///< Successful 65 | } 66 | 67 | static inline bool gpb_cbuff_Reset(gpb_cbuff_t *cb) 68 | { 69 | cb->count = 0; 70 | cb->head = 0; 71 | cb->tail = 0; 72 | return true; ///< Successful 73 | } 74 | 75 | static inline bool gpb_cbuff_Enqueue(gpb_cbuff_t *cb, uint8_t b) 76 | { 77 | // Full 78 | if (cb->count >= cb->capacity) 79 | return false; ///< Failed 80 | // Push value 81 | cb->buffer[cb->head] = b; 82 | // Increment head 83 | cb->head = (cb->head + 1) % cb->capacity; 84 | cb->count = cb->count + 1; 85 | return true; ///< Successful 86 | } 87 | 88 | static inline bool gpb_cbuff_Dequeue(gpb_cbuff_t *cb, uint8_t *b) 89 | { 90 | // Empty 91 | if (cb->count == 0) 92 | return false; ///< Failed 93 | // Pop value 94 | *b = cb->buffer[cb->tail]; 95 | // Increment tail 96 | cb->tail = (cb->tail + 1) % cb->capacity; 97 | cb->count = cb->count - 1; 98 | return true; ///< Successful 99 | } 100 | 101 | static inline bool gpb_cbuff_Dequeue_Peek(gpb_cbuff_t *cb, uint8_t *b, uint32_t offset) 102 | { 103 | // Empty 104 | if (cb->count == 0) 105 | return false; ///< Failed 106 | if (cb->count < offset) 107 | return false; ///< Failed 108 | // Pop value 109 | *b = cb->buffer[(cb->tail + offset) % cb->capacity]; 110 | return true; ///< Successful 111 | } 112 | 113 | static inline size_t gpb_cbuff_Capacity(gpb_cbuff_t *cb) { return cb->capacity;} 114 | static inline size_t gpb_cbuff_Count(gpb_cbuff_t *cb) { return cb->count;} 115 | static inline bool gpb_cbuff_IsFull(gpb_cbuff_t *cb) { return (cb->count >= cb->capacity);} 116 | static inline bool gpb_cbuff_IsEmpty(gpb_cbuff_t *cb) { return (cb->count == 0);} 117 | 118 | #ifdef FEATURE_CHECKSUM_SUPPORTED 119 | /* Temp Enqeue */ 120 | static inline bool gpb_cbuff_ResetTemp(gpb_cbuff_t *cb) 121 | { 122 | cb->countTemp = 0; 123 | cb->headTemp = cb->head ; 124 | } 125 | 126 | static inline bool gpb_cbuff_AcceptTemp(gpb_cbuff_t *cb) 127 | { 128 | cb->count += cb->countTemp; 129 | cb->head = cb->headTemp ; 130 | return true; ///< Successful 131 | } 132 | 133 | static inline bool gpb_cbuff_EnqueueTemp(gpb_cbuff_t *cb, uint8_t b) 134 | { 135 | // Full 136 | if (cb->countTemp >= (cb->capacity - cb->count)) 137 | return false; ///< Failed 138 | // Push value 139 | cb->buffer[cb->headTemp] = b; 140 | // Increment headTemp 141 | cb->headTemp = (cb->headTemp + 1) % cb->capacity; 142 | cb->countTemp = cb->countTemp + 1; 143 | return true; ///< Successful 144 | } 145 | #else 146 | #define gpb_cbuff_EnqueueTemp(CB, B) gpb_cbuff_Enqueue(CB, B) 147 | #endif // FEATURE_CHECKSUM_SUPPORTED 148 | 149 | #endif // GBP_CBUFF_H -------------------------------------------------------------------------------- /NeoGB_Printer/includes/gblink/gbp_pkt.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * 3 | * Gameboy Printer Packet Parser 4 | * Part of GAMEBOY PRINTER EMULATION PROJECT V2 (Arduino) 5 | * Copyright (C) 2020 Brian Khuu 6 | * 7 | * PURPOSE: This module focus on parsing a stream of bytes as gbp packets 8 | * LICENCE: 9 | * This file is part of Arduino Gameboy Printer Emulator. 10 | * 11 | * Arduino Gameboy Printer Emulator is free software: 12 | * you can redistribute it and/or modify it under the terms of the 13 | * GNU General Public License as published by the Free Software Foundation, 14 | * either version 3 of the License, or (at your option) any later version. 15 | * 16 | * Arduino Gameboy Printer Emulator is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with Arduino Gameboy Printer Emulator. If not, see . 23 | */ 24 | 25 | #include // uint8_t 26 | #include // size_t 27 | #include // bool 28 | #include "gameboy_printer_protocol.h" 29 | 30 | #define GBP_PKT_PAYLOAD_BUFF_SIZE_IN_BYTE GBP_TILE_SIZE_IN_BYTE 31 | 32 | typedef enum 33 | { 34 | GBP_REC_NONE, 35 | GBP_REC_GOT_PACKET, 36 | /* Streaming Packet */ 37 | GBP_REC_GOT_PAYLOAD_PARTAL, 38 | GBP_REC_GOT_PACKET_END 39 | } gbp_received_t; 40 | 41 | typedef struct 42 | { 43 | gbp_received_t received; 44 | uint16_t pktByteIndex; 45 | 46 | /* Packet Information */ 47 | uint8_t command; 48 | uint8_t compression; 49 | uint16_t dataLength; 50 | uint8_t printerID; 51 | uint8_t status; 52 | 53 | /* Decompressor */ 54 | size_t buffIndex; 55 | bool compressedRun; 56 | bool repeatByteGet; 57 | uint8_t repeatByte; 58 | uint8_t loopRunLength; 59 | 60 | } gbp_pkt_t; 61 | 62 | typedef struct 63 | { 64 | // This is the tile data accumulator 65 | unsigned char count; 66 | unsigned char tile[GBP_TILE_SIZE_IN_BYTE]; 67 | } gbp_pkt_tileAcc_t; 68 | 69 | 70 | bool gbp_pkt_init(gbp_pkt_t *_pkt); 71 | bool gbp_pkt_reset(gbp_pkt_t *_pkt); 72 | bool gbp_pkt_processByte(gbp_pkt_t *_pkt, const uint8_t _byte, uint8_t buffer[], uint8_t *bufferSize, const size_t bufferMax); 73 | bool gbp_pkt_decompressor(gbp_pkt_t *_pkt, const uint8_t buff[], const size_t buffSize, gbp_pkt_tileAcc_t *tileBuff); 74 | bool gbp_pkt_tileAccu_tileReadyCheck(gbp_pkt_tileAcc_t *tileBuff); 75 | 76 | /******************************************************************************* 77 | * Print Instruction 78 | *******************************************************************************/ 79 | 80 | static inline int gbp_pkt_printInstruction_num_of_sheets(uint8_t payloadBuff[GBP_PRINT_INSTRUCT_PAYLOAD_SIZE]) 81 | { 82 | return (payloadBuff[GBP_PRINT_INSTRUCT_INDEX_NUM_OF_SHEETS ]); 83 | } 84 | 85 | static inline int gbp_pkt_printInstruction_num_of_linefeed_before_print(uint8_t payloadBuff[GBP_PRINT_INSTRUCT_PAYLOAD_SIZE]) 86 | { 87 | return (payloadBuff[GBP_PRINT_INSTRUCT_INDEX_NUM_OF_LINEFEED] >> 4) & 0x0F; 88 | } 89 | 90 | static inline int gbp_pkt_printInstruction_num_of_linefeed_after_print(uint8_t payloadBuff[GBP_PRINT_INSTRUCT_PAYLOAD_SIZE]) 91 | { 92 | return (payloadBuff[GBP_PRINT_INSTRUCT_INDEX_NUM_OF_LINEFEED]) & 0x0F; 93 | } 94 | 95 | static inline int gbp_pkt_printInstruction_palette_value(uint8_t payloadBuff[GBP_PRINT_INSTRUCT_PAYLOAD_SIZE]) 96 | { 97 | return (payloadBuff[GBP_PRINT_INSTRUCT_INDEX_PALETTE_VALUE ]); 98 | } 99 | 100 | static inline int gbp_pkt_printInstruction_print_density(uint8_t payloadBuff[GBP_PRINT_INSTRUCT_PAYLOAD_SIZE]) 101 | { 102 | return (payloadBuff[GBP_PRINT_INSTRUCT_INDEX_PRINT_DENSITY ]); 103 | } 104 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/gblink/gbp_serial_io.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * 3 | * Gameboy Printer Serial IO 4 | * Part of GAMEBOY PRINTER EMULATION PROJECT V2 (Arduino) 5 | * Copyright (C) 2020 Brian Khuu 6 | * 7 | * PURPOSE: This module focus on capturing packets from a gameboy to a virtual printer 8 | * LICENCE: 9 | * This file is part of Arduino Gameboy Printer Emulator. 10 | * 11 | * Arduino Gameboy Printer Emulator is free software: 12 | * you can redistribute it and/or modify it under the terms of the 13 | * GNU General Public License as published by the Free Software Foundation, 14 | * either version 3 of the License, or (at your option) any later version. 15 | * 16 | * Arduino Gameboy Printer Emulator is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with Arduino Gameboy Printer Emulator. If not, see . 23 | */ 24 | #ifndef GBP_SERIAL_IO_H 25 | #define GBP_SERIAL_IO_H 26 | #include // uint8_t 27 | #include // size_t 28 | #include // bool 29 | 30 | #define GBP_FEATURE_USING_RISING_CLOCK_ONLY_ISR // Away from technical accuracy towards double speed mode compatibility 31 | 32 | /******************************************************************************/ 33 | 34 | /* Init/Reset/ISR Functions */ 35 | bool gpb_serial_io_init(size_t buffSize, uint8_t *buffPtr); 36 | bool gpb_serial_io_reset(void); 37 | #ifdef GBP_FEATURE_USING_RISING_CLOCK_ONLY_ISR 38 | bool gpb_serial_io_OnRising_ISR(const bool GBP_SOUT); 39 | #else 40 | bool gpb_serial_io_OnChange_ISR(const bool GBP_SCLK, const bool GBP_SOUT); 41 | #endif 42 | 43 | /* Timeout */ 44 | bool gbp_serial_io_timeout_handler(uint32_t elapsed_ms); 45 | 46 | /* Output */ 47 | size_t gbp_serial_io_dataBuff_getByteCount(void); 48 | uint8_t gbp_serial_io_dataBuff_getByte(void); 49 | uint8_t gbp_serial_io_dataBuff_getByte_Peek(uint32_t offset); 50 | uint16_t gbp_serial_io_dataBuff_waterline(bool resetWaterline); 51 | uint16_t gbp_serial_io_dataBuff_max(void); 52 | 53 | void gbp_serial_io_print_done(); 54 | void gbp_serial_io_print_set(); 55 | bool gbp_serial_io_should_print(); 56 | 57 | /******************************************************************************/ 58 | #endif 59 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/gblink/gbp_tiles.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * 3 | * Gameboy Printer Tile Decoder 4 | * Part of GAMEBOY PRINTER EMULATION PROJECT V2 (Arduino) 5 | * Copyright (C) 2020 Brian Khuu 6 | * 7 | * PURPOSE: This module focus on decoder gameboy printer tiles to bmp 8 | * LICENCE: 9 | * This file is part of Arduino Gameboy Printer Emulator. 10 | * 11 | * Arduino Gameboy Printer Emulator is free software: 12 | * you can redistribute it and/or modify it under the terms of the 13 | * GNU General Public License as published by the Free Software Foundation, 14 | * either version 3 of the License, or (at your option) any later version. 15 | * 16 | * Arduino Gameboy Printer Emulator is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with Arduino Gameboy Printer Emulator. If not, see . 23 | */ 24 | 25 | #include // uint8_t 26 | #include // size_t 27 | #include // bool 28 | #include "gameboy_printer_protocol.h" 29 | 30 | /* 31 | Dev Note: From https://gbdev.io/pandocs/Gameboy_Printer.html 32 | GBP has about 8 KiB of RAM to buffer incoming graphics data. 33 | Those 8 KiB allow a maximum bitmap area of 160*200 (8192/160*4) pixels between prints. 34 | 35 | ``` 36 | buffSize = 8*1024; 37 | bitsPerPixel = 2; 38 | linePixelCount = 8*20; 39 | linebitcount = bitsPerPixel * linePixelCount; 40 | bytesPerLine = linebitcount / 8; 41 | maxRows = buffSize / (bytesPerLine * 8) 42 | maxRows = 25.6 43 | ``` 44 | */ 45 | 46 | // IMAGE DEFINITION 47 | #define GBP_TILE_PIXEL_WIDTH 8 48 | #define GBP_TILE_PIXEL_HEIGHT 8 49 | #define GBP_TILES_PER_LINE 20 50 | #define GBP_TILES_PER_ROW 26 // Number of supported lines between print commands (26 tile row height is based on the 8KiB of a real gbp printer) 51 | #define GBP_TILE_MAX_TONES 4 // 2bits per pixel 52 | 53 | // 2B per pixel packing 54 | #define GBP_TILE_2BIT_LINEPACK_INDEX(x) (x/4) 55 | #define GBP_TILE_2BIT_LINEPACK_BITOFFSET(x) (2*(x%4)) 56 | #define GBP_TILE_2BIT_LINEPACK_IN_BYTE_COUNT (4) ///< 4 2bit pixel in 8bit byte 57 | #define GBP_TILE_2BIT_LINEPACK_ROWSIZE_B(byteCount) (byteCount/4) ///< Row sized when 2bit packed is reduced by factor of 4 58 | 59 | typedef struct 60 | { 61 | // This is the tile to bmp decoder 62 | uint16_t tileLineOffset; 63 | uint16_t tileRowOffset; 64 | uint16_t tileRowOffsetHarmonised; 65 | 66 | // Each array entry represents a decoded 2bit pixel 67 | uint8_t bmpLineBuffer[GBP_TILE_PIXEL_HEIGHT * GBP_TILES_PER_ROW][GBP_TILE_2BIT_LINEPACK_ROWSIZE_B(GBP_TILE_PIXEL_WIDTH * GBP_TILES_PER_LINE)]; 68 | } gbp_tile_t; 69 | 70 | bool gbp_tiles_line_decoder(gbp_tile_t *gbp_tiles, const uint8_t tileBuff[GBP_TILE_SIZE_IN_BYTE]); 71 | void gbp_tiles_reset(gbp_tile_t *gbp_tiles); 72 | void gbp_tiles_print(gbp_tile_t *gbp_tiles, uint8_t sheet, uint8_t linefeed, uint8_t pallet, uint8_t density); 73 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/PNGenc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // PNG Decoder 3 | // 4 | // written by Larry Bank 5 | // bitbank@pobox.com 6 | // Arduino port started 5/3/2021 7 | // Original PNG code written 20+ years ago :) 8 | // The goal of this code is to decode PNG images on embedded systems 9 | // 10 | // Copyright 2021 BitBank Software, Inc. All Rights Reserved. 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | //=========================================================================== 21 | // 22 | #include "PNGenc.h" 23 | 24 | // Include the C code which does the actual work 25 | #include "png.h" 26 | 27 | // 28 | // File (SD/MMC) based initialization 29 | // 30 | int PNG::open(const char *szFilename, PNG_OPEN_CALLBACK *pfnOpen, PNG_CLOSE_CALLBACK *pfnClose, PNG_READ_CALLBACK *pfnRead, PNG_WRITE_CALLBACK *pfnWrite, PNG_SEEK_CALLBACK *pfnSeek) 31 | { 32 | memset(&_png, 0, sizeof(PNGIMAGE)); 33 | _png.iTransparent = -1; 34 | _png.pfnRead = pfnRead; 35 | _png.pfnWrite = pfnWrite; 36 | _png.pfnSeek = pfnSeek; 37 | _png.pfnOpen = pfnOpen; 38 | _png.pfnClose = pfnClose; 39 | _png.PNGFile.fHandle = (*pfnOpen)(szFilename); 40 | if (_png.PNGFile.fHandle == NULL) { 41 | _png.iError = PNG_INVALID_FILE; 42 | return PNG_INVALID_FILE; 43 | } 44 | return PNG_SUCCESS; 45 | 46 | } /* open() */ 47 | 48 | int PNG::open(uint8_t *pOutput, int iBufferSize) 49 | { 50 | memset(&_png, 0, sizeof(PNGIMAGE)); 51 | _png.iTransparent = -1; 52 | _png.pOutput = pOutput; 53 | _png.iBufferSize = iBufferSize; 54 | return PNG_SUCCESS; 55 | } /* open() */ 56 | 57 | // 58 | // return the last error (if any) 59 | // 60 | int PNG::getLastError() 61 | { 62 | return _png.iError; 63 | } /* getLastError() */ 64 | // 65 | // Close the file - not needed when decoding from memory 66 | // 67 | int PNG::close() 68 | { 69 | if (_png.pfnClose) 70 | (*_png.pfnClose)(&_png.PNGFile); 71 | return _png.iDataSize; 72 | } /* close() */ 73 | 74 | int PNG::encodeBegin(int iWidth, int iHeight, uint8_t ucPixelType, uint8_t ucBpp, uint8_t *pPalette, uint8_t ucCompLevel) 75 | { 76 | _png.iWidth = iWidth; 77 | _png.iHeight = iHeight; 78 | _png.ucPixelType = ucPixelType; 79 | _png.ucBpp = ucBpp; 80 | if (pPalette != NULL) 81 | memcpy(_png.ucPalette, pPalette, 768); // save 256 color entries 82 | _png.ucCompLevel = ucCompLevel; 83 | _png.y = 0; 84 | return PNG_SUCCESS; 85 | } /* encodeBegin() */ 86 | 87 | int PNG::addLine(uint8_t *pPixels) 88 | { 89 | int rc; 90 | rc = PNGAddLine(&_png, pPixels, _png.y); 91 | _png.y++; 92 | return rc; 93 | } /* addLine() */ 94 | 95 | int PNG::setTransparentColor(uint32_t u32Color) 96 | { 97 | if (_png.ucPixelType == PNG_PIXEL_GRAYSCALE || _png.ucPixelType == PNG_PIXEL_TRUECOLOR) { 98 | _png.iTransparent = u32Color; 99 | return PNG_SUCCESS; 100 | } 101 | else 102 | return PNG_INVALID_PARAMETER; // indexed image must have palette alpha values 103 | } /* setTransparentColor() */ 104 | 105 | int PNG::setAlphaPalette(uint8_t *pPalette) 106 | { 107 | if (pPalette != NULL && _png.ucPixelType == PNG_PIXEL_INDEXED) { 108 | _png.ucHasAlphaPalette = 1; 109 | memcpy(&_png.ucPalette[768], pPalette, 256); // capture up to 256 alpha values 110 | return PNG_SUCCESS; 111 | } 112 | return PNG_INVALID_PARAMETER; 113 | } /* setAlphaPalette() */ 114 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/PNGenc.h: -------------------------------------------------------------------------------- 1 | // 2 | // PNG Encoder 3 | // 4 | // written by Larry Bank 5 | // bitbank@pobox.com 6 | // Arduino port started 6/27/2021 7 | // Original PNG code written 20+ years ago :) 8 | // The goal of this code is to decode PNG images on embedded systems 9 | // 10 | // Copyright 2021 BitBank Software, Inc. All Rights Reserved. 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | //=========================================================================== 21 | // 22 | #ifndef __PNGENC__ 23 | #define __PNGENC__ 24 | #if defined( __MACH__ ) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) 25 | #include 26 | #include 27 | #include 28 | #include 29 | #define memcpy_P memcpy 30 | #define PROGMEM 31 | #else 32 | #include 33 | #endif 34 | #include "zutil.h" 35 | #include "deflate.h" 36 | // 37 | // PNG Encoder 38 | // Written by Larry Bank 39 | // Copyright (c) 2021 BitBank Software, Inc. 40 | // 41 | // Designed to encode PNG files from source images (1-32 bpp) 42 | // using less than 100K of RAM 43 | // 44 | #ifndef FALSE 45 | #define FALSE 0 46 | #define TRUE 1 47 | #endif 48 | // Number of bits to reduce the zlib window size 49 | // 0 = 256K + 6K needed 50 | // 1 = 128K + 6K needed 51 | // 2 = 64K ... 52 | #define MEM_SHRINK 3 53 | 54 | /* Defines and variables */ 55 | #define PNG_FILE_BUF_SIZE 2048 56 | #define PNG_FILE_HIGHWATER ((PNG_FILE_BUF_SIZE * 3)/4) 57 | // Number of bytes to reserve for current and previous lines 58 | // Defaults to 640 32-bit pixels max width 59 | #define PNG_MAX_BUFFERED_PIXELS (640*4 + 1) 60 | // PNG filter type 61 | enum { 62 | PNG_FILTER_NONE=0, 63 | PNG_FILTER_SUB, 64 | PNG_FILTER_UP, 65 | PNG_FILTER_AVG, 66 | PNG_FILTER_PAETH, 67 | PNG_FILTER_COUNT 68 | }; 69 | 70 | // decode options 71 | enum { 72 | PNG_CHECK_CRC = 1, 73 | PNG_FAST_PALETTE = 2 74 | }; 75 | 76 | // source pixel type 77 | enum { 78 | PNG_PIXEL_GRAYSCALE=0, 79 | PNG_PIXEL_TRUECOLOR=2, 80 | PNG_PIXEL_INDEXED=3, 81 | PNG_PIXEL_GRAY_ALPHA=4, 82 | PNG_PIXEL_TRUECOLOR_ALPHA=6 83 | }; 84 | 85 | // Error codes returned by getLastError() 86 | enum { 87 | PNG_SUCCESS = 0, 88 | PNG_INVALID_PARAMETER, 89 | PNG_ENCODE_ERROR, 90 | PNG_MEM_ERROR, 91 | PNG_NO_BUFFER, 92 | PNG_UNSUPPORTED_FEATURE, 93 | PNG_INVALID_FILE, 94 | PNG_TOO_BIG 95 | }; 96 | 97 | typedef struct png_file_tag 98 | { 99 | int32_t iPos; // current file position 100 | int32_t iSize; // file size 101 | uint8_t *pData; // memory file pointer 102 | void * fHandle; // class pointer to File/SdFat or whatever you want 103 | } PNGFILE; 104 | 105 | // Callback function prototypes 106 | typedef int32_t (PNG_READ_CALLBACK)(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen); 107 | typedef int32_t (PNG_WRITE_CALLBACK)(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen); 108 | typedef int32_t (PNG_SEEK_CALLBACK)(PNGFILE *pFile, int32_t iPosition); 109 | typedef void * (PNG_OPEN_CALLBACK)(const char *szFilename); 110 | typedef void (PNG_CLOSE_CALLBACK)(PNGFILE *pFile); 111 | 112 | // 113 | // our private structure to hold a JPEG image decode state 114 | // 115 | typedef struct png_image_tag 116 | { 117 | int iWidth, iHeight, y, iTransparent; // image size 118 | uint8_t ucBpp, ucPixelType, ucCompLevel, ucHasAlphaPalette; 119 | uint8_t ucMemType; 120 | uint8_t *pOutput; 121 | int iBufferSize; // output buffer size provided by caller 122 | int iHeaderSize; // size of the PNG header 123 | int iCompressedSize; // size of flate output 124 | int iDataSize; // total output file size 125 | int iMemPool; // memory allocated out of memory pool 126 | int iPitch; // bytes per line 127 | int iError; 128 | PNG_READ_CALLBACK *pfnRead; 129 | PNG_WRITE_CALLBACK *pfnWrite; 130 | PNG_SEEK_CALLBACK *pfnSeek; 131 | PNG_OPEN_CALLBACK *pfnOpen; 132 | PNG_CLOSE_CALLBACK *pfnClose; 133 | PNGFILE PNGFile; 134 | z_stream c_stream; /* compression stream */ 135 | uint8_t ucPalette[1024]; 136 | uint8_t ucMemPool[sizeof(deflate_state) + (0x40000 >> MEM_SHRINK)]; // RAM needed for deflate 137 | uint8_t ucPrevLine[PNG_MAX_BUFFERED_PIXELS]; 138 | uint8_t ucCurrLine[PNG_MAX_BUFFERED_PIXELS]; 139 | uint8_t ucFileBuf[PNG_FILE_BUF_SIZE]; // holds temp file data 140 | } PNGIMAGE; 141 | 142 | #ifdef __cplusplus 143 | #define PNG_STATIC static 144 | // 145 | // The PNG class wraps portable C code which does the actual work 146 | // 147 | class PNG 148 | { 149 | public: 150 | int open(const char *szFilename, PNG_OPEN_CALLBACK *pfnOpen, PNG_CLOSE_CALLBACK *pfnClose, PNG_READ_CALLBACK *pfnRead, PNG_WRITE_CALLBACK *pfnWrite, PNG_SEEK_CALLBACK *pfnSeek); 151 | int open(uint8_t *pOutput, int iBufferSize); 152 | int close(); 153 | int encodeBegin(int iWidth, int iHeight, uint8_t iPixelType, uint8_t iBpp, uint8_t *pPalette, uint8_t iCompLevel); 154 | int addLine(uint8_t *pPixels); 155 | int setTransparentColor(uint32_t u32Color); 156 | int setAlphaPalette(uint8_t *pPalette); 157 | int getLastError(); 158 | 159 | private: 160 | PNGIMAGE _png; 161 | }; 162 | #else 163 | #define PNG_STATIC 164 | int PNG_openRAM(PNGIMAGE *pPNG, uint8_t *pData, int iDataSize); 165 | int PNG_openFile(PNGIMAGE *pPNG, const char *szFilename); 166 | int PNG_encodeBegin(PNGIMAGE *pPNG, int iWidth, int iHeight, uint8_t ucPixelType, uint8_t *pPalette, uint8_t ucCompLevel); 167 | void PNG_encodeEnd(PNGIMAGE *pPNG); 168 | int addLine(PNGIMAGE *, uint8_t *pPixels); 169 | int setTransparentColor(PNGIMAGE *pPNG, uint32_t u32Color); 170 | int setAlphaPalette(PNGIMAGE *pPNG, uint8_t *pPalette); 171 | int PNG_getLastError(PNGIMAGE *pPNG); 172 | #endif // __cplusplus 173 | 174 | // Due to unaligned memory causing an exception, we have to do these macros the slow way 175 | #define INTELSHORT(p) ((*p) + (*(p+1)<<8)) 176 | #define INTELLONG(p) ((*p) + (*(p+1)<<8) + (*(p+2)<<16) + (*(p+3)<<24)) 177 | #define MOTOSHORT(p) (((*(p))<<8) + (*(p+1))) 178 | #define MOTOLONG(p) (((*p)<<24) + ((*(p+1))<<16) + ((*(p+2))<<8) + (*(p+3))) 179 | 180 | // Must be a 32-bit target processor 181 | #define REGISTER_WIDTH 32 182 | 183 | #endif // __PNGENC__ 184 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/adler32.c: -------------------------------------------------------------------------------- 1 | /* adler32.c -- compute the Adler-32 checksum of a data stream 2 | * Copyright (C) 1995-2011, 2016 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "zutil.h" 9 | 10 | local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); 11 | 12 | #define BASE 65521U /* largest prime smaller than 65536 */ 13 | #define NMAX 5552 14 | /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 15 | 16 | #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} 17 | #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 18 | #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 19 | #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 20 | #define DO16(buf) DO8(buf,0); DO8(buf,8); 21 | 22 | /* use NO_DIVIDE if your processor does not do division in hardware -- 23 | try it both ways to see which is faster */ 24 | #ifdef NO_DIVIDE 25 | /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 26 | (thank you to John Reiser for pointing this out) */ 27 | # define CHOP(a) \ 28 | do { \ 29 | unsigned long tmp = a >> 16; \ 30 | a &= 0xffffUL; \ 31 | a += (tmp << 4) - tmp; \ 32 | } while (0) 33 | # define MOD28(a) \ 34 | do { \ 35 | CHOP(a); \ 36 | if (a >= BASE) a -= BASE; \ 37 | } while (0) 38 | # define MOD(a) \ 39 | do { \ 40 | CHOP(a); \ 41 | MOD28(a); \ 42 | } while (0) 43 | # define MOD63(a) \ 44 | do { /* this assumes a is not negative */ \ 45 | z_off64_t tmp = a >> 32; \ 46 | a &= 0xffffffffL; \ 47 | a += (tmp << 8) - (tmp << 5) + tmp; \ 48 | tmp = a >> 16; \ 49 | a &= 0xffffL; \ 50 | a += (tmp << 4) - tmp; \ 51 | tmp = a >> 16; \ 52 | a &= 0xffffL; \ 53 | a += (tmp << 4) - tmp; \ 54 | if (a >= BASE) a -= BASE; \ 55 | } while (0) 56 | #else 57 | # define MOD(a) a %= BASE 58 | # define MOD28(a) a %= BASE 59 | # define MOD63(a) a %= BASE 60 | #endif 61 | 62 | /* ========================================================================= */ 63 | uLong ZEXPORT adler32_z(adler, buf, len) 64 | uLong adler; 65 | const Bytef *buf; 66 | z_size_t len; 67 | { 68 | unsigned long sum2; 69 | unsigned n; 70 | 71 | /* split Adler-32 into component sums */ 72 | sum2 = (adler >> 16) & 0xffff; 73 | adler &= 0xffff; 74 | 75 | /* in case user likes doing a byte at a time, keep it fast */ 76 | if (len == 1) { 77 | adler += buf[0]; 78 | if (adler >= BASE) 79 | adler -= BASE; 80 | sum2 += adler; 81 | if (sum2 >= BASE) 82 | sum2 -= BASE; 83 | return adler | (sum2 << 16); 84 | } 85 | 86 | /* initial Adler-32 value (deferred check for len == 1 speed) */ 87 | if (buf == Z_NULL) 88 | return 1L; 89 | 90 | /* in case short lengths are provided, keep it somewhat fast */ 91 | if (len < 16) { 92 | while (len--) { 93 | adler += *buf++; 94 | sum2 += adler; 95 | } 96 | if (adler >= BASE) 97 | adler -= BASE; 98 | MOD28(sum2); /* only added so many BASE's */ 99 | return adler | (sum2 << 16); 100 | } 101 | 102 | /* do length NMAX blocks -- requires just one modulo operation */ 103 | while (len >= NMAX) { 104 | len -= NMAX; 105 | n = NMAX / 16; /* NMAX is divisible by 16 */ 106 | do { 107 | DO16(buf); /* 16 sums unrolled */ 108 | buf += 16; 109 | } while (--n); 110 | MOD(adler); 111 | MOD(sum2); 112 | } 113 | 114 | /* do remaining bytes (less than NMAX, still just one modulo) */ 115 | if (len) { /* avoid modulos if none remaining */ 116 | while (len >= 16) { 117 | len -= 16; 118 | DO16(buf); 119 | buf += 16; 120 | } 121 | while (len--) { 122 | adler += *buf++; 123 | sum2 += adler; 124 | } 125 | MOD(adler); 126 | MOD(sum2); 127 | } 128 | 129 | /* return recombined sums */ 130 | return adler | (sum2 << 16); 131 | } 132 | 133 | /* ========================================================================= */ 134 | uLong ZEXPORT adler32(adler, buf, len) 135 | uLong adler; 136 | const Bytef *buf; 137 | uInt len; 138 | { 139 | return adler32_z(adler, buf, len); 140 | } 141 | 142 | /* ========================================================================= */ 143 | local uLong adler32_combine_(adler1, adler2, len2) 144 | uLong adler1; 145 | uLong adler2; 146 | z_off64_t len2; 147 | { 148 | unsigned long sum1; 149 | unsigned long sum2; 150 | unsigned rem; 151 | 152 | /* for negative len, return invalid adler32 as a clue for debugging */ 153 | if (len2 < 0) 154 | return 0xffffffffUL; 155 | 156 | /* the derivation of this formula is left as an exercise for the reader */ 157 | MOD63(len2); /* assumes len2 >= 0 */ 158 | rem = (unsigned)len2; 159 | sum1 = adler1 & 0xffff; 160 | sum2 = rem * sum1; 161 | MOD(sum2); 162 | sum1 += (adler2 & 0xffff) + BASE - 1; 163 | sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 164 | if (sum1 >= BASE) sum1 -= BASE; 165 | if (sum1 >= BASE) sum1 -= BASE; 166 | if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); 167 | if (sum2 >= BASE) sum2 -= BASE; 168 | return sum1 | (sum2 << 16); 169 | } 170 | 171 | /* ========================================================================= */ 172 | uLong ZEXPORT adler32_combine(adler1, adler2, len2) 173 | uLong adler1; 174 | uLong adler2; 175 | z_off_t len2; 176 | { 177 | return adler32_combine_(adler1, adler2, len2); 178 | } 179 | 180 | uLong ZEXPORT adler32_combine64(adler1, adler2, len2) 181 | uLong adler1; 182 | uLong adler2; 183 | z_off64_t len2; 184 | { 185 | return adler32_combine_(adler1, adler2, len2); 186 | } 187 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/gzguts.h: -------------------------------------------------------------------------------- 1 | /* gzguts.h -- zlib internal header definitions for gz* operations 2 | * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | #ifdef _LARGEFILE64_SOURCE 7 | # ifndef _LARGEFILE_SOURCE 8 | # define _LARGEFILE_SOURCE 1 9 | # endif 10 | # ifdef _FILE_OFFSET_BITS 11 | # undef _FILE_OFFSET_BITS 12 | # endif 13 | #endif 14 | 15 | #ifdef HAVE_HIDDEN 16 | # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) 17 | #else 18 | # define ZLIB_INTERNAL 19 | #endif 20 | 21 | #include 22 | #include "zlib.h" 23 | #ifdef STDC 24 | # include 25 | # include 26 | # include 27 | #endif 28 | 29 | #ifndef _POSIX_SOURCE 30 | # define _POSIX_SOURCE 31 | #endif 32 | #include 33 | 34 | #ifdef _WIN32 35 | # include 36 | #endif 37 | 38 | #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) 39 | # include 40 | #endif 41 | 42 | #if defined(_WIN32) || defined(__CYGWIN__) 43 | # define WIDECHAR 44 | #endif 45 | 46 | #ifdef WINAPI_FAMILY 47 | # define open _open 48 | # define read _read 49 | # define write _write 50 | # define close _close 51 | #endif 52 | 53 | #ifdef NO_DEFLATE /* for compatibility with old definition */ 54 | # define NO_GZCOMPRESS 55 | #endif 56 | 57 | #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) 58 | # ifndef HAVE_VSNPRINTF 59 | # define HAVE_VSNPRINTF 60 | # endif 61 | #endif 62 | 63 | #if defined(__CYGWIN__) 64 | # ifndef HAVE_VSNPRINTF 65 | # define HAVE_VSNPRINTF 66 | # endif 67 | #endif 68 | 69 | #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) 70 | # ifndef HAVE_VSNPRINTF 71 | # define HAVE_VSNPRINTF 72 | # endif 73 | #endif 74 | 75 | #ifndef HAVE_VSNPRINTF 76 | # ifdef MSDOS 77 | /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), 78 | but for now we just assume it doesn't. */ 79 | # define NO_vsnprintf 80 | # endif 81 | # ifdef __TURBOC__ 82 | # define NO_vsnprintf 83 | # endif 84 | # ifdef WIN32 85 | /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ 86 | # if !defined(vsnprintf) && !defined(NO_vsnprintf) 87 | # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) 88 | # define vsnprintf _vsnprintf 89 | # endif 90 | # endif 91 | # endif 92 | # ifdef __SASC 93 | # define NO_vsnprintf 94 | # endif 95 | # ifdef VMS 96 | # define NO_vsnprintf 97 | # endif 98 | # ifdef __OS400__ 99 | # define NO_vsnprintf 100 | # endif 101 | # ifdef __MVS__ 102 | # define NO_vsnprintf 103 | # endif 104 | #endif 105 | 106 | /* unlike snprintf (which is required in C99), _snprintf does not guarantee 107 | null termination of the result -- however this is only used in gzlib.c where 108 | the result is assured to fit in the space provided */ 109 | #if defined(_MSC_VER) && _MSC_VER < 1900 110 | # define snprintf _snprintf 111 | #endif 112 | 113 | #ifndef local 114 | # define local static 115 | #endif 116 | /* since "static" is used to mean two completely different things in C, we 117 | define "local" for the non-static meaning of "static", for readability 118 | (compile with -Dlocal if your debugger can't find static symbols) */ 119 | 120 | /* gz* functions always use library allocation functions */ 121 | #ifndef STDC 122 | extern voidp malloc OF((uInt size)); 123 | extern void free OF((voidpf ptr)); 124 | #endif 125 | 126 | /* get errno and strerror definition */ 127 | #if defined UNDER_CE 128 | # include 129 | # define zstrerror() gz_strwinerror((DWORD)GetLastError()) 130 | #else 131 | # ifndef NO_STRERROR 132 | # include 133 | # define zstrerror() strerror(errno) 134 | # else 135 | # define zstrerror() "stdio error (consult errno)" 136 | # endif 137 | #endif 138 | 139 | /* provide prototypes for these when building zlib without LFS */ 140 | #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 141 | ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); 142 | ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); 143 | ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); 144 | ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); 145 | #endif 146 | 147 | /* default memLevel */ 148 | #if MAX_MEM_LEVEL >= 8 149 | # define DEF_MEM_LEVEL 8 150 | #else 151 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 152 | #endif 153 | 154 | /* default i/o buffer size -- double this for output when reading (this and 155 | twice this must be able to fit in an unsigned type) */ 156 | #define GZBUFSIZE 8192 157 | 158 | /* gzip modes, also provide a little integrity check on the passed structure */ 159 | #define GZ_NONE 0 160 | #define GZ_READ 7247 161 | #define GZ_WRITE 31153 162 | #define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ 163 | 164 | /* values for gz_state how */ 165 | #define LOOK 0 /* look for a gzip header */ 166 | #define COPY 1 /* copy input directly */ 167 | #define GZIP 2 /* decompress a gzip stream */ 168 | 169 | /* internal gzip file state data structure */ 170 | typedef struct { 171 | /* exposed contents for gzgetc() macro */ 172 | struct gzFile_s x; /* "x" for exposed */ 173 | /* x.have: number of bytes available at x.next */ 174 | /* x.next: next output data to deliver or write */ 175 | /* x.pos: current position in uncompressed data */ 176 | /* used for both reading and writing */ 177 | int mode; /* see gzip modes above */ 178 | int fd; /* file descriptor */ 179 | char *path; /* path or fd for error messages */ 180 | unsigned size; /* buffer size, zero if not allocated yet */ 181 | unsigned want; /* requested buffer size, default is GZBUFSIZE */ 182 | unsigned char *in; /* input buffer (double-sized when writing) */ 183 | unsigned char *out; /* output buffer (double-sized when reading) */ 184 | int direct; /* 0 if processing gzip, 1 if transparent */ 185 | /* just for reading */ 186 | int how; /* 0: get header, 1: copy, 2: decompress */ 187 | z_off64_t start; /* where the gzip data started, for rewinding */ 188 | int eof; /* true if end of input file reached */ 189 | int past; /* true if read requested past end */ 190 | /* just for writing */ 191 | int level; /* compression level */ 192 | int strategy; /* compression strategy */ 193 | /* seek request */ 194 | z_off64_t skip; /* amount to skip (already rewound if backwards) */ 195 | int seek; /* true if seek request pending */ 196 | /* error information */ 197 | int err; /* error code */ 198 | char *msg; /* error message */ 199 | /* zlib inflate or deflate stream */ 200 | z_stream strm; /* stream structure in-place (not a pointer) */ 201 | } gz_state; 202 | typedef gz_state FAR *gz_statep; 203 | 204 | /* shared functions */ 205 | void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); 206 | #if defined UNDER_CE 207 | char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); 208 | #endif 209 | 210 | /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t 211 | value -- needed when comparing unsigned to z_off64_t, which is signed 212 | (possible z_off64_t types off_t, off64_t, and long are all signed) */ 213 | #ifdef INT_MAX 214 | # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) 215 | #else 216 | unsigned ZLIB_INTERNAL gz_intmax OF((void)); 217 | # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) 218 | #endif 219 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/trees.h: -------------------------------------------------------------------------------- 1 | /* header created automatically with -DGEN_TREES_H */ 2 | 3 | local const ct_data static_ltree[L_CODES+2] = { 4 | {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, 5 | {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, 6 | {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, 7 | {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, 8 | {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, 9 | {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, 10 | {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, 11 | {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, 12 | {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, 13 | {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, 14 | {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, 15 | {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, 16 | {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, 17 | {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, 18 | {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, 19 | {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, 20 | {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, 21 | {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, 22 | {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, 23 | {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, 24 | {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, 25 | {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, 26 | {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, 27 | {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, 28 | {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, 29 | {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, 30 | {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, 31 | {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, 32 | {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, 33 | {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, 34 | {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, 35 | {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, 36 | {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, 37 | {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, 38 | {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, 39 | {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, 40 | {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, 41 | {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, 42 | {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, 43 | {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, 44 | {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, 45 | {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, 46 | {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, 47 | {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, 48 | {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, 49 | {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, 50 | {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, 51 | {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, 52 | {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, 53 | {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, 54 | {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, 55 | {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, 56 | {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, 57 | {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, 58 | {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, 59 | {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, 60 | {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, 61 | {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} 62 | }; 63 | 64 | local const ct_data static_dtree[D_CODES] = { 65 | {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, 66 | {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, 67 | {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, 68 | {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, 69 | {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, 70 | {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} 71 | }; 72 | 73 | const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { 74 | 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 75 | 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 76 | 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 77 | 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 78 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 79 | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 80 | 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 81 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 84 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 87 | 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 88 | 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 89 | 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 90 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 91 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 92 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 93 | 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 94 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 95 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 96 | 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 97 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 98 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 99 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 100 | }; 101 | 102 | const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { 103 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 104 | 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 105 | 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 106 | 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 107 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 108 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 109 | 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 110 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 111 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 112 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 113 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 114 | 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 115 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 116 | }; 117 | 118 | local const int base_length[LENGTH_CODES] = { 119 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 120 | 64, 80, 96, 112, 128, 160, 192, 224, 0 121 | }; 122 | 123 | local const int base_dist[D_CODES] = { 124 | 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 125 | 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 126 | 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 127 | }; 128 | 129 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/zutil.c: -------------------------------------------------------------------------------- 1 | /* zutil.c -- target dependent utility functions for the compression library 2 | * Copyright (C) 1995-2017 Jean-loup Gailly 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "zutil.h" 9 | #ifndef Z_SOLO 10 | # include "gzguts.h" 11 | #endif 12 | 13 | z_const char * const z_errmsg[10] = { 14 | (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ 15 | (z_const char *)"stream end", /* Z_STREAM_END 1 */ 16 | (z_const char *)"", /* Z_OK 0 */ 17 | (z_const char *)"file error", /* Z_ERRNO (-1) */ 18 | (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ 19 | (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ 20 | (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ 21 | (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ 22 | (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ 23 | (z_const char *)"" 24 | }; 25 | 26 | 27 | const char * ZEXPORT zlibVersion() 28 | { 29 | return ZLIB_VERSION; 30 | } 31 | 32 | uLong ZEXPORT zlibCompileFlags() 33 | { 34 | uLong flags; 35 | 36 | flags = 0; 37 | switch ((int)(sizeof(uInt))) { 38 | case 2: break; 39 | case 4: flags += 1; break; 40 | case 8: flags += 2; break; 41 | default: flags += 3; 42 | } 43 | switch ((int)(sizeof(uLong))) { 44 | case 2: break; 45 | case 4: flags += 1 << 2; break; 46 | case 8: flags += 2 << 2; break; 47 | default: flags += 3 << 2; 48 | } 49 | switch ((int)(sizeof(voidpf))) { 50 | case 2: break; 51 | case 4: flags += 1 << 4; break; 52 | case 8: flags += 2 << 4; break; 53 | default: flags += 3 << 4; 54 | } 55 | switch ((int)(sizeof(z_off_t))) { 56 | case 2: break; 57 | case 4: flags += 1 << 6; break; 58 | case 8: flags += 2 << 6; break; 59 | default: flags += 3 << 6; 60 | } 61 | #ifdef ZLIB_DEBUG 62 | flags += 1 << 8; 63 | #endif 64 | #if defined(ASMV) || defined(ASMINF) 65 | flags += 1 << 9; 66 | #endif 67 | #ifdef ZLIB_WINAPI 68 | flags += 1 << 10; 69 | #endif 70 | #ifdef BUILDFIXED 71 | flags += 1 << 12; 72 | #endif 73 | #ifdef DYNAMIC_CRC_TABLE 74 | flags += 1 << 13; 75 | #endif 76 | #ifdef NO_GZCOMPRESS 77 | flags += 1L << 16; 78 | #endif 79 | #ifdef NO_GZIP 80 | flags += 1L << 17; 81 | #endif 82 | #ifdef PKZIP_BUG_WORKAROUND 83 | flags += 1L << 20; 84 | #endif 85 | #ifdef FASTEST 86 | flags += 1L << 21; 87 | #endif 88 | #if defined(STDC) || defined(Z_HAVE_STDARG_H) 89 | # ifdef NO_vsnprintf 90 | flags += 1L << 25; 91 | # ifdef HAS_vsprintf_void 92 | flags += 1L << 26; 93 | # endif 94 | # else 95 | # ifdef HAS_vsnprintf_void 96 | flags += 1L << 26; 97 | # endif 98 | # endif 99 | #else 100 | flags += 1L << 24; 101 | # ifdef NO_snprintf 102 | flags += 1L << 25; 103 | # ifdef HAS_sprintf_void 104 | flags += 1L << 26; 105 | # endif 106 | # else 107 | # ifdef HAS_snprintf_void 108 | flags += 1L << 26; 109 | # endif 110 | # endif 111 | #endif 112 | return flags; 113 | } 114 | 115 | #ifdef ZLIB_DEBUG 116 | #include 117 | # ifndef verbose 118 | # define verbose 0 119 | # endif 120 | int ZLIB_INTERNAL z_verbose = verbose; 121 | 122 | void ZLIB_INTERNAL z_error (m) 123 | char *m; 124 | { 125 | fprintf(stderr, "%s\n", m); 126 | exit(1); 127 | } 128 | #endif 129 | 130 | /* exported to allow conversion of error code to string for compress() and 131 | * uncompress() 132 | */ 133 | const char * ZEXPORT zError(err) 134 | int err; 135 | { 136 | return ERR_MSG(err); 137 | } 138 | 139 | #if defined(_WIN32_WCE) 140 | /* The Microsoft C Run-Time Library for Windows CE doesn't have 141 | * errno. We define it as a global variable to simplify porting. 142 | * Its value is always 0 and should not be used. 143 | */ 144 | int errno = 0; 145 | #endif 146 | 147 | #ifndef HAVE_MEMCPY 148 | 149 | void ZLIB_INTERNAL zmemcpy(dest, source, len) 150 | Bytef* dest; 151 | const Bytef* source; 152 | uInt len; 153 | { 154 | if (len == 0) return; 155 | do { 156 | *dest++ = *source++; /* ??? to be unrolled */ 157 | } while (--len != 0); 158 | } 159 | 160 | int ZLIB_INTERNAL zmemcmp(s1, s2, len) 161 | const Bytef* s1; 162 | const Bytef* s2; 163 | uInt len; 164 | { 165 | uInt j; 166 | 167 | for (j = 0; j < len; j++) { 168 | if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; 169 | } 170 | return 0; 171 | } 172 | 173 | void ZLIB_INTERNAL zmemzero(dest, len) 174 | Bytef* dest; 175 | uInt len; 176 | { 177 | if (len == 0) return; 178 | do { 179 | *dest++ = 0; /* ??? to be unrolled */ 180 | } while (--len != 0); 181 | } 182 | #endif 183 | 184 | #ifndef Z_SOLO 185 | 186 | #ifdef SYS16BIT 187 | 188 | #ifdef __TURBOC__ 189 | /* Turbo C in 16-bit mode */ 190 | 191 | # define MY_ZCALLOC 192 | 193 | /* Turbo C malloc() does not allow dynamic allocation of 64K bytes 194 | * and farmalloc(64K) returns a pointer with an offset of 8, so we 195 | * must fix the pointer. Warning: the pointer must be put back to its 196 | * original form in order to free it, use zcfree(). 197 | */ 198 | 199 | #define MAX_PTR 10 200 | /* 10*64K = 640K */ 201 | 202 | local int next_ptr = 0; 203 | 204 | typedef struct ptr_table_s { 205 | voidpf org_ptr; 206 | voidpf new_ptr; 207 | } ptr_table; 208 | 209 | local ptr_table table[MAX_PTR]; 210 | /* This table is used to remember the original form of pointers 211 | * to large buffers (64K). Such pointers are normalized with a zero offset. 212 | * Since MSDOS is not a preemptive multitasking OS, this table is not 213 | * protected from concurrent access. This hack doesn't work anyway on 214 | * a protected system like OS/2. Use Microsoft C instead. 215 | */ 216 | 217 | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) 218 | { 219 | voidpf buf; 220 | ulg bsize = (ulg)items*size; 221 | 222 | (void)opaque; 223 | 224 | /* If we allocate less than 65520 bytes, we assume that farmalloc 225 | * will return a usable pointer which doesn't have to be normalized. 226 | */ 227 | if (bsize < 65520L) { 228 | buf = farmalloc(bsize); 229 | if (*(ush*)&buf != 0) return buf; 230 | } else { 231 | buf = farmalloc(bsize + 16L); 232 | } 233 | if (buf == NULL || next_ptr >= MAX_PTR) return NULL; 234 | table[next_ptr].org_ptr = buf; 235 | 236 | /* Normalize the pointer to seg:0 */ 237 | *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; 238 | *(ush*)&buf = 0; 239 | table[next_ptr++].new_ptr = buf; 240 | return buf; 241 | } 242 | 243 | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) 244 | { 245 | int n; 246 | 247 | (void)opaque; 248 | 249 | if (*(ush*)&ptr != 0) { /* object < 64K */ 250 | farfree(ptr); 251 | return; 252 | } 253 | /* Find the original pointer */ 254 | for (n = 0; n < next_ptr; n++) { 255 | if (ptr != table[n].new_ptr) continue; 256 | 257 | farfree(table[n].org_ptr); 258 | while (++n < next_ptr) { 259 | table[n-1] = table[n]; 260 | } 261 | next_ptr--; 262 | return; 263 | } 264 | Assert(0, "zcfree: ptr not found"); 265 | } 266 | 267 | #endif /* __TURBOC__ */ 268 | 269 | 270 | #ifdef M_I86 271 | /* Microsoft C in 16-bit mode */ 272 | 273 | # define MY_ZCALLOC 274 | 275 | #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) 276 | # define _halloc halloc 277 | # define _hfree hfree 278 | #endif 279 | 280 | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) 281 | { 282 | (void)opaque; 283 | return _halloc((long)items, size); 284 | } 285 | 286 | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) 287 | { 288 | (void)opaque; 289 | _hfree(ptr); 290 | } 291 | 292 | #endif /* M_I86 */ 293 | 294 | #endif /* SYS16BIT */ 295 | 296 | 297 | #ifndef MY_ZCALLOC /* Any system without a special alloc function */ 298 | 299 | //#ifndef STDC 300 | //extern voidp malloc OF((uInt size)); 301 | //extern voidp calloc OF((uInt items, uInt size)); 302 | //extern void free OF((voidpf ptr)); 303 | //#endif 304 | 305 | //voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) 306 | // voidpf opaque; 307 | // unsigned items; 308 | // unsigned size; 309 | //{ 310 | // (void)opaque; 311 | // return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : 312 | // (voidpf)calloc(items, size); 313 | //} 314 | 315 | //void ZLIB_INTERNAL zcfree (opaque, ptr) 316 | // voidpf opaque; 317 | // voidpf ptr; 318 | //{ 319 | // (void)opaque; 320 | // free(ptr); 321 | //} 322 | 323 | #endif /* MY_ZCALLOC */ 324 | 325 | #endif /* !Z_SOLO */ 326 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/PNGenc/zutil.h: -------------------------------------------------------------------------------- 1 | /* zutil.h -- internal interface and configuration of the compression library 2 | * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* @(#) $Id$ */ 12 | 13 | #ifndef ZUTIL_H 14 | #define ZUTIL_H 15 | 16 | #ifdef HAVE_HIDDEN 17 | # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) 18 | #else 19 | # define ZLIB_INTERNAL 20 | #endif 21 | 22 | #include "zlib.h" 23 | 24 | #if defined(STDC) && !defined(Z_SOLO) 25 | # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) 26 | # include 27 | # endif 28 | # include 29 | # include 30 | #endif 31 | 32 | #ifdef Z_SOLO 33 | typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ 34 | #endif 35 | 36 | #ifndef local 37 | # define local static 38 | #endif 39 | /* since "static" is used to mean two completely different things in C, we 40 | define "local" for the non-static meaning of "static", for readability 41 | (compile with -Dlocal if your debugger can't find static symbols) */ 42 | 43 | typedef unsigned char uch; 44 | typedef uch FAR uchf; 45 | typedef unsigned short ush; 46 | typedef ush FAR ushf; 47 | typedef unsigned long ulg; 48 | 49 | extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ 50 | /* (size given to avoid silly warnings with Visual C++) */ 51 | 52 | #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] 53 | 54 | #define ERR_RETURN(strm,err) \ 55 | return (strm->msg = ERR_MSG(err), (err)) 56 | /* To be used only when the state is known to be valid */ 57 | 58 | /* common constants */ 59 | 60 | #ifndef DEF_WBITS 61 | # define DEF_WBITS MAX_WBITS 62 | #endif 63 | /* default windowBits for decompression. MAX_WBITS is for compression only */ 64 | 65 | #if MAX_MEM_LEVEL >= 8 66 | # define DEF_MEM_LEVEL 8 67 | #else 68 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 69 | #endif 70 | /* default memLevel */ 71 | 72 | #define STORED_BLOCK 0 73 | #define STATIC_TREES 1 74 | #define DYN_TREES 2 75 | /* The three kinds of block type */ 76 | 77 | #define MIN_MATCH 3 78 | #define MAX_MATCH 258 79 | /* The minimum and maximum match lengths */ 80 | 81 | #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ 82 | 83 | /* target dependencies */ 84 | 85 | #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) 86 | # define OS_CODE 0x00 87 | # ifndef Z_SOLO 88 | # if defined(__TURBOC__) || defined(__BORLANDC__) 89 | # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) 90 | /* Allow compilation with ANSI keywords only enabled */ 91 | void _Cdecl farfree( void *block ); 92 | void *_Cdecl farmalloc( unsigned long nbytes ); 93 | # else 94 | # include 95 | # endif 96 | # else /* MSC or DJGPP */ 97 | # include 98 | # endif 99 | # endif 100 | #endif 101 | 102 | #ifdef AMIGA 103 | # define OS_CODE 1 104 | #endif 105 | 106 | #if defined(VAXC) || defined(VMS) 107 | # define OS_CODE 2 108 | # define F_OPEN(name, mode) \ 109 | fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") 110 | #endif 111 | 112 | #ifdef __370__ 113 | # if __TARGET_LIB__ < 0x20000000 114 | # define OS_CODE 4 115 | # elif __TARGET_LIB__ < 0x40000000 116 | # define OS_CODE 11 117 | # else 118 | # define OS_CODE 8 119 | # endif 120 | #endif 121 | 122 | #if defined(ATARI) || defined(atarist) 123 | # define OS_CODE 5 124 | #endif 125 | 126 | #ifdef OS2 127 | # define OS_CODE 6 128 | # if defined(M_I86) && !defined(Z_SOLO) 129 | # include 130 | # endif 131 | #endif 132 | 133 | #if defined(MACOS) || defined(TARGET_OS_MAC) 134 | # define OS_CODE 7 135 | # ifndef Z_SOLO 136 | # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os 137 | # include /* for fdopen */ 138 | # else 139 | # ifndef fdopen 140 | # define fdopen(fd,mode) NULL /* No fdopen() */ 141 | # endif 142 | # endif 143 | # endif 144 | #endif 145 | 146 | #ifdef __acorn 147 | # define OS_CODE 13 148 | #endif 149 | 150 | #if defined(WIN32) && !defined(__CYGWIN__) 151 | # define OS_CODE 10 152 | #endif 153 | 154 | #ifdef _BEOS_ 155 | # define OS_CODE 16 156 | #endif 157 | 158 | #ifdef __TOS_OS400__ 159 | # define OS_CODE 18 160 | #endif 161 | 162 | #ifdef __APPLE__ 163 | # define OS_CODE 19 164 | #endif 165 | 166 | #if defined(_BEOS_) || defined(RISCOS) 167 | # define fdopen(fd,mode) NULL /* No fdopen() */ 168 | #endif 169 | 170 | #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX 171 | # if defined(_WIN32_WCE) 172 | # define fdopen(fd,mode) NULL /* No fdopen() */ 173 | # ifndef _PTRDIFF_T_DEFINED 174 | typedef int ptrdiff_t; 175 | # define _PTRDIFF_T_DEFINED 176 | # endif 177 | # else 178 | # define fdopen(fd,type) _fdopen(fd,type) 179 | # endif 180 | #endif 181 | 182 | #if defined(__BORLANDC__) && !defined(MSDOS) 183 | #pragma warn -8004 184 | #pragma warn -8008 185 | #pragma warn -8066 186 | #endif 187 | 188 | /* provide prototypes for these when building zlib without LFS */ 189 | #if !defined(_WIN32) && \ 190 | (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) 191 | ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); 192 | ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); 193 | #endif 194 | 195 | /* common defaults */ 196 | 197 | #ifndef OS_CODE 198 | # define OS_CODE 3 /* assume Unix */ 199 | #endif 200 | 201 | #ifndef F_OPEN 202 | # define F_OPEN(name, mode) fopen((name), (mode)) 203 | #endif 204 | 205 | /* functions */ 206 | 207 | #if defined(pyr) || defined(Z_SOLO) 208 | # define NO_MEMCPY 209 | #endif 210 | #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) 211 | /* Use our own functions for small and medium model with MSC <= 5.0. 212 | * You may have to use the same strategy for Borland C (untested). 213 | * The __SC__ check is for Symantec. 214 | */ 215 | # define NO_MEMCPY 216 | #endif 217 | #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) 218 | # define HAVE_MEMCPY 219 | #endif 220 | #ifdef HAVE_MEMCPY 221 | # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ 222 | # define zmemcpy _fmemcpy 223 | # define zmemcmp _fmemcmp 224 | # define zmemzero(dest, len) _fmemset(dest, 0, len) 225 | # else 226 | # define zmemcpy memcpy 227 | # define zmemcmp memcmp 228 | # define zmemzero(dest, len) memset(dest, 0, len) 229 | # endif 230 | #else 231 | void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); 232 | int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); 233 | void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); 234 | #endif 235 | 236 | /* Diagnostic functions */ 237 | #ifdef ZLIB_DEBUG 238 | # include 239 | extern int ZLIB_INTERNAL z_verbose; 240 | extern void ZLIB_INTERNAL z_error OF((char *m)); 241 | # define Assert(cond,msg) {if(!(cond)) z_error(msg);} 242 | # define Trace(x) {if (z_verbose>=0) fprintf x ;} 243 | # define Tracev(x) {if (z_verbose>0) fprintf x ;} 244 | # define Tracevv(x) {if (z_verbose>1) fprintf x ;} 245 | # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} 246 | # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} 247 | #else 248 | # define Assert(cond,msg) 249 | # define Trace(x) 250 | # define Tracev(x) 251 | # define Tracevv(x) 252 | # define Tracec(c,x) 253 | # define Tracecv(c,x) 254 | #endif 255 | 256 | #ifndef Z_SOLO 257 | voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, 258 | unsigned size)); 259 | void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); 260 | #endif 261 | 262 | #define ZALLOC(strm, items, size) \ 263 | (*((strm)->zalloc))((strm)->opaque, (items), (size)) 264 | #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) 265 | #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} 266 | 267 | /* Reverse the bytes in a 32-bit value */ 268 | #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ 269 | (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) 270 | 271 | #endif /* ZUTIL_H */ 272 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/bmp_FixedWidthStream.h: -------------------------------------------------------------------------------- 1 | /* 24-bit BMP (Bitmap) ANSI C header library 2 | * This is free and unencumbered software released into the public domain. 3 | * https://github.com/skeeto/bmp 4 | */ 5 | // MODIFICATION: Allow for delayed writing of the header section while 6 | // an image of unknown height but known width is streamed in 7 | // BMP_COMPAT removed as it is pointless when only sticking to streaming 8 | // This was modified to make it easier to stream to file in embedded system 9 | // chunk by chunk... assumes fixed width but variable height 10 | 11 | #ifndef BMP_H 12 | #define BMP_H 13 | 14 | #define BMP_SIZE(w, h) ((h) * ((w) * 3 + (((w) * -3UL) & 3)) + 14 + 40) 15 | 16 | #define BMP_PIXEL_START_OFFSET 54 17 | #define BMP_PIXEL_BUFF_SIZE(bufw, bufh) ((bufh) * ((bufw) * 3 + (((bufw) * -3UL) & 3))) 18 | 19 | static unsigned long 20 | bmp_size(long width, long height) 21 | { 22 | long pad = ((width % 4) * -3UL) & 3; /* Overflow-safe */ 23 | if (width < 1 || height < 1) 24 | return 0; /* Illegal size */ 25 | else if (width > ((0x7fffffffL - 14 - 40) / height - pad) / 3) 26 | return 0; /* Overflow */ 27 | else 28 | return height * (width * 3 + pad) + 14 + 40; 29 | } 30 | 31 | static void 32 | bmp_header(unsigned char buf[], long width, long height) 33 | { 34 | long pad; 35 | unsigned long size; 36 | unsigned long uw = width; 37 | unsigned long uh = -height; 38 | 39 | /* bfType */ 40 | buf[0] = 0x42u; ///< 'B' 41 | buf[1] = 0x4Du; ///< 'M' 42 | 43 | /* bfSize */ 44 | pad = (width * -3UL) & 3; 45 | size = height * (width * 3 + pad) + 14 + 40; 46 | buf[2] = (unsigned char)(size >> 0); 47 | buf[3] = (unsigned char)(size >> 8); 48 | buf[4] = (unsigned char)(size >> 16); 49 | buf[5] = (unsigned char)(size >> 24); 50 | 51 | /* bfReserved1 + bfReserved2 */ 52 | buf[6] = 0x00u; 53 | buf[7] = 0x00u; 54 | buf[8] = 0x00u; 55 | buf[9] = 0x00u; 56 | 57 | /* bfOffBits */ 58 | buf[10] = 0x36u; 59 | buf[11] = 0x00u; 60 | buf[12] = 0x00u; 61 | buf[13] = 0x00u; 62 | 63 | /* biSize */ 64 | buf[14] = 0x28u; 65 | buf[15] = 0x00u; 66 | buf[16] = 0x00u; 67 | buf[17] = 0x00u; 68 | 69 | /* biWidth */ 70 | buf[18] = uw >> 0; 71 | buf[19] = uw >> 8; 72 | buf[20] = uw >> 16; 73 | buf[21] = uw >> 24; 74 | 75 | /* biHeight */ 76 | buf[22] = uh >> 0; 77 | buf[23] = uh >> 8; 78 | buf[24] = uh >> 16; 79 | buf[25] = uh >> 24; 80 | 81 | /* biPlanes */ 82 | buf[26] = 0x01; 83 | buf[27] = 0x00; 84 | 85 | /* biBitCount */ 86 | buf[28] = 0x18; 87 | buf[29] = 0x00; 88 | 89 | /* biCompression */ 90 | buf[30] = 0x00; 91 | buf[31] = 0x00; 92 | buf[32] = 0x00; 93 | buf[33] = 0x00; 94 | 95 | /* biSizeImage */ 96 | buf[34] = 0x00; 97 | buf[35] = 0x00; 98 | buf[36] = 0x00; 99 | buf[37] = 0x00; 100 | 101 | /* biXPelsPerMeter */ 102 | buf[38] = 0x00; 103 | buf[39] = 0x00; 104 | buf[40] = 0x00; 105 | buf[41] = 0x00; 106 | 107 | /* biYPelsPerMeter */ 108 | buf[42] = 0x00; 109 | buf[43] = 0x00; 110 | buf[44] = 0x00; 111 | buf[45] = 0x00; 112 | 113 | /* biClrUsed */ 114 | buf[46] = 0x00; 115 | buf[47] = 0x00; 116 | buf[48] = 0x00; 117 | buf[49] = 0x00; 118 | 119 | /* biClrImportant */ 120 | buf[50] = 0x00; 121 | buf[51] = 0x00; 122 | buf[52] = 0x00; 123 | buf[53] = 0x00; 124 | } 125 | 126 | static long 127 | bmp_pixelBufferSize(unsigned long width, long height) 128 | { 129 | const long pad = (width * -3UL) & 3; 130 | return height * (width * 3 + pad); 131 | } 132 | 133 | static void 134 | bmp_set(unsigned char buf[], unsigned long width, long x, long y, unsigned long color) 135 | { 136 | long pad = (width * -3UL) & 3; 137 | long byteOffset = (y) * (width * 3 + pad) + x * 3; 138 | buf[byteOffset + 0] = color >> 0; 139 | buf[byteOffset + 1] = color >> 8; 140 | buf[byteOffset + 2] = color >> 16; 141 | } 142 | 143 | static unsigned long 144 | bmp_get(unsigned char buf[], unsigned long width, long x, long y) 145 | { 146 | long pad = (width * -3UL) & 3; 147 | long byteOffset = (y) * (width * 3 + pad) + x * 3; 148 | return (unsigned long)buf[byteOffset + 0] << 0 | 149 | (unsigned long)buf[byteOffset + 1] << 8 | 150 | (unsigned long)buf[byteOffset + 2] << 16; 151 | } 152 | 153 | static unsigned long 154 | bmp_encode(float r, float g, float b) 155 | { 156 | unsigned long ur = r * 255.0f + 0.5f; 157 | unsigned long ug = g * 255.0f + 0.5f; 158 | unsigned long ub = b * 255.0f + 0.5f; 159 | return ub | ug << 8 | ur << 16; 160 | } 161 | 162 | static void 163 | bmp_decode(unsigned long c, float *r, float *g, float *b) 164 | { 165 | unsigned long ur = c >> 16 & 0xff; 166 | unsigned long ug = c >> 8 & 0xff; 167 | unsigned long ub = c >> 0 & 0xff; 168 | *r = ur / 255.0f; 169 | *g = ug / 255.0f; 170 | *b = ub / 255.0f; 171 | } 172 | 173 | #endif /* BMP_H */ 174 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/image/gbp_bmp.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "bmp_FixedWidthStream.h" 6 | 7 | 8 | // Image Rendering 9 | #define GBP_BMP_MAX_TILE_HEIGHT 1 10 | #define GBP_BMP_WIDTH (GBP_TILE_PIXEL_WIDTH * GBP_TILES_PER_LINE) 11 | #define GBP_BMP_HEIGHT (GBP_TILE_PIXEL_HEIGHT * GBP_BMP_MAX_TILE_HEIGHT) 12 | 13 | typedef struct 14 | { 15 | FILE *f; 16 | int fileCounter; 17 | uint16_t bmpSizeWidth; // x 18 | uint16_t bmpSizeHeight; // y 19 | unsigned char bmpBuffer[BMP_PIXEL_BUFF_SIZE(GBP_BMP_WIDTH, GBP_BMP_HEIGHT)]; 20 | } gbp_bmp_t; 21 | 22 | 23 | bool gbp_bmp_isopen(gbp_bmp_t * gbp_bmp); 24 | void gbp_bmp_open(gbp_bmp_t * gbp_bmp, const char *outputFilename, const uint16_t fixed_width_size); 25 | void gbp_bmp_add(gbp_bmp_t * gbp_bmp, const uint8_t * bmpLineBuffer, const uint16_t sizex, const uint16_t sizey, const uint32_t palletColor[4]); 26 | void gbp_bmp_render(gbp_bmp_t * gbp_bmp); 27 | -------------------------------------------------------------------------------- /NeoGB_Printer/includes/led/LED_status.h: -------------------------------------------------------------------------------- 1 | ////minimal RGB LED support by Raphaël BOICHOT 2 | #include "./config.h" 3 | 4 | void LED_led_ON(int COLOR1) 5 | { 6 | #ifndef LED_STATUS_PIN 7 | int LED_STATUS_PIN = -1; 8 | #endif 9 | if(COLOR1 == LED_STATUS_PIN){ 10 | digitalWrite(COLOR1, HIGH); 11 | }else{ 12 | #ifdef COMMON_ANODE 13 | digitalWrite(COLOR1, LOW); 14 | #endif 15 | #ifdef COMMON_CATHODE 16 | digitalWrite(COLOR1, HIGH); 17 | #endif 18 | } 19 | } 20 | void LED_led_ON(int COLOR1, int COLOR2){ 21 | #ifdef COMMON_ANODE 22 | digitalWrite(COLOR1, LOW); 23 | digitalWrite(COLOR2, LOW); 24 | #endif 25 | #ifdef COMMON_CATHODE 26 | digitalWrite(COLOR1, HIGH); 27 | digitalWrite(COLOR2, HIGH); 28 | #endif 29 | } 30 | void LED_led_ON(int COLOR1, int COLOR2, int COLOR3){ 31 | #ifdef COMMON_ANODE 32 | digitalWrite(COLOR1, LOW); 33 | digitalWrite(COLOR2, LOW); 34 | digitalWrite(COLOR3, LOW); 35 | #endif 36 | #ifdef COMMON_CATHODE 37 | digitalWrite(COLOR1, HIGH); 38 | digitalWrite(COLOR2, HIGH); 39 | digitalWrite(COLOR3, HIGH); 40 | #endif 41 | } 42 | 43 | void LED_led_OFF(int COLOR1) 44 | { 45 | #ifndef LED_STATUS_PIN 46 | int LED_STATUS_PIN = -1; 47 | #endif 48 | if(COLOR1 == LED_STATUS_PIN){ 49 | digitalWrite(COLOR1, LOW); 50 | }else{ 51 | #ifdef COMMON_ANODE 52 | digitalWrite(COLOR1, HIGH); 53 | #endif 54 | #ifdef COMMON_CATHODE 55 | digitalWrite(COLOR1, LOW); 56 | #endif 57 | } 58 | } 59 | void LED_led_OFF(int COLOR1, int COLOR2) 60 | { 61 | #ifdef COMMON_ANODE 62 | digitalWrite(COLOR1, HIGH); 63 | digitalWrite(COLOR2, HIGH); 64 | #endif 65 | #ifdef COMMON_CATHODE 66 | digitalWrite(COLOR1, LOW); 67 | digitalWrite(COLOR2, LOW); 68 | #endif 69 | } 70 | void LED_led_OFF(int COLOR1, int COLOR2, int COLOR3) 71 | { 72 | #ifdef COMMON_ANODE 73 | digitalWrite(COLOR1, HIGH); 74 | digitalWrite(COLOR2, HIGH); 75 | digitalWrite(COLOR3, HIGH); 76 | #endif 77 | #ifdef COMMON_CATHODE 78 | digitalWrite(COLOR1, LOW); 79 | digitalWrite(COLOR2, LOW); 80 | digitalWrite(COLOR3, LOW); 81 | #endif 82 | } 83 | 84 | void LED_blink(int COLOR1, int number, int delay_on, int delay_off) 85 | { 86 | #ifndef LED_STATUS_PIN 87 | int LED_STATUS_PIN = -1; 88 | #endif 89 | if(COLOR1 == LED_STATUS_PIN){ 90 | for (int j = 1; j <= number; j++) { 91 | digitalWrite(COLOR1, HIGH); 92 | delay(delay_on); 93 | digitalWrite(COLOR1, LOW); 94 | delay(delay_off); 95 | } 96 | }else{ 97 | for (int j = 1; j <= number; j++) { 98 | #ifdef COMMON_ANODE 99 | digitalWrite(COLOR1, LOW); 100 | #endif 101 | #ifdef COMMON_CATHODE 102 | digitalWrite(COLOR1, HIGH); 103 | #endif 104 | delay(delay_on); 105 | #ifdef COMMON_ANODE 106 | digitalWrite(COLOR1, HIGH); 107 | #endif 108 | #ifdef COMMON_CATHODE 109 | digitalWrite(COLOR1, LOW); 110 | #endif 111 | delay(delay_off); 112 | } 113 | } 114 | 115 | } 116 | void LED_blink(int COLOR1, int COLOR2, int number, int delay_on, int delay_off) 117 | { 118 | for (int j = 1; j <= number; j++) { 119 | #ifdef COMMON_ANODE 120 | digitalWrite(COLOR1, LOW); 121 | digitalWrite(COLOR2, LOW); 122 | #endif 123 | #ifdef COMMON_CATHODE 124 | digitalWrite(COLOR1, HIGH); 125 | digitalWrite(COLOR2, HIGH); 126 | #endif 127 | delay(delay_on); 128 | #ifdef COMMON_ANODE 129 | digitalWrite(COLOR1, HIGH); 130 | digitalWrite(COLOR2, HIGH); 131 | #endif 132 | #ifdef COMMON_CATHODE 133 | digitalWrite(COLOR1, LOW); 134 | digitalWrite(COLOR2, LOW); 135 | #endif 136 | delay(delay_off); 137 | } 138 | } 139 | void LED_blink(int COLOR1, int COLOR2, int COLOR3, int number, int delay_on, int delay_off) 140 | { 141 | for (int j = 1; j <= number; j++) { 142 | #ifdef COMMON_ANODE 143 | digitalWrite(COLOR1, LOW); 144 | digitalWrite(COLOR2, LOW); 145 | digitalWrite(COLOR3, LOW); 146 | #endif 147 | #ifdef COMMON_CATHODE 148 | digitalWrite(COLOR1, HIGH); 149 | digitalWrite(COLOR2, HIGH); 150 | digitalWrite(COLOR3, HIGH); 151 | #endif 152 | delay(delay_on); 153 | #ifdef COMMON_ANODE 154 | digitalWrite(COLOR1, HIGH); 155 | digitalWrite(COLOR2, HIGH); 156 | digitalWrite(COLOR3, HIGH); 157 | #endif 158 | #ifdef COMMON_CATHODE 159 | digitalWrite(COLOR1, LOW); 160 | digitalWrite(COLOR2, LOW); 161 | digitalWrite(COLOR3, LOW); 162 | #endif 163 | delay(delay_off); 164 | } 165 | } 166 | 167 | void LED_init() 168 | { 169 | #if defined(COMMON_ANODE) || defined(COMMON_CATHODE) 170 | pinMode(LED_STATUS_RED, OUTPUT); 171 | pinMode(LED_STATUS_GREEN, OUTPUT); 172 | pinMode(LED_STATUS_BLUE, OUTPUT); 173 | #endif 174 | #ifdef LED_STATUS_PIN 175 | pinMode(LED_STATUS_PIN, OUTPUT); 176 | #endif 177 | 178 | #ifdef COMMON_ANODE 179 | digitalWrite(LED_STATUS_RED, HIGH); 180 | digitalWrite(LED_STATUS_GREEN, HIGH); 181 | digitalWrite(LED_STATUS_BLUE, HIGH); 182 | #endif 183 | #ifdef COMMON_CATHODE 184 | digitalWrite(LED_STATUS_RED, LOW); 185 | digitalWrite(LED_STATUS_GREEN, LOW); 186 | digitalWrite(LED_STATUS_BLUE, LOW); 187 | #endif 188 | #ifdef LED_STATUS_PIN 189 | digitalWrite(LED_STATUS_PIN, LOW); 190 | #endif 191 | } 192 | -------------------------------------------------------------------------------- /NeoGB_Printer/oled.ino: -------------------------------------------------------------------------------- 1 | #ifdef USE_OLED 2 | 3 | #include "./includes/display/oled_graphics.h" 4 | 5 | #define PRINTER_ICON_HEIGHT 27 6 | #define PRINTER_ICON_WIDTH 32 7 | 8 | #define OLED_WHITE 0xFFFF 9 | #define OLED_BLACK 0x0000 10 | 11 | #ifdef USE_SSD1306 //oled images 128x32 12 | #include "./includes/display/SSD1306.hpp" 13 | static LGFX_SSD1306 display; // LGFX_SSD1306のインスタンス(クラスLGFX_SSD1306を使ってlcdでいろいろできるようにする)を作成 14 | #endif 15 | 16 | #ifdef USE_SSD1331 //oled images 96x64 17 | #include "./includes/display/SSD1331.hpp" 18 | static LGFX_SSD1331 display; // LGFX_SSD1331のインスタンス(クラスLGFX_SSD1306を使ってlcdでいろいろできるようにする)を作成 19 | #endif 20 | 21 | uint8_t prevlcdStatus=9; 22 | 23 | void oled_setup() { 24 | display.init(); 25 | #ifdef OLED_ROTATE 26 | display.setRotation(2); 27 | #else 28 | display.setRotation(0); 29 | #endif 30 | } 31 | 32 | void oled_writeNumImages(int numTotDump) { 33 | char textshow[15]; 34 | 35 | display.setTextSize(1); 36 | display.setTextColor(OLED_WHITE); 37 | 38 | sprintf(textshow, "%d Dumps", numTotDump); 39 | 40 | #ifdef USE_SSD1306 41 | display.setCursor(56, 15); 42 | #endif 43 | #ifdef USE_SSD1331 44 | display.setCursor(get_xoffset(String(textshow)), 47); 45 | #endif 46 | 47 | display.println(textshow); 48 | 49 | #ifdef USE_SSD1306 50 | display.setCursor(56, 23); 51 | #endif 52 | #ifdef USE_SSD1331 53 | display.setCursor(get_xoffset(String(numVersion)), 56); 54 | #endif 55 | 56 | display.println(numVersion); 57 | } 58 | 59 | void oled_ShowIP() { 60 | display.setTextSize(1); 61 | display.setTextColor(OLED_WHITE); 62 | 63 | #ifdef USE_SSD1306 64 | display.setCursor(0, 13); 65 | #endif 66 | #ifdef USE_SSD1331 67 | display.setCursor(get_xoffset(ip), 47); 68 | #endif 69 | display.println(ip); 70 | 71 | #ifdef USE_SSD1306 72 | display.setCursor(0, 23); 73 | #endif 74 | #ifdef USE_SSD1331 75 | display.setCursor(get_xoffset(mdnsName + ".local"), 56); 76 | #endif 77 | display.println(mdnsName + ".local"); 78 | } 79 | 80 | int get_xoffset(String message) { 81 | return ((round(SCREEN_WIDTH / 6) - message.length()) / 2) * 6; 82 | } 83 | 84 | void oled_drawStatus(const unsigned char statusName[]) { 85 | display.fillScreen(OLED_BLACK); 86 | display.drawBitmap(0, 0, statusName, SCREEN_WIDTH, SCREEN_HEIGHT, OLED_WHITE); 87 | } 88 | 89 | 90 | void oledStateChange(uint8_t lcdStatus){ 91 | if(prevlcdStatus != lcdStatus){ 92 | switch (lcdStatus) 93 | { 94 | case 0: 95 | oled_drawStatus(splashScreen); 96 | break; 97 | case 1: 98 | oled_drawStatus(idlePrinter); 99 | break; 100 | case 2: 101 | oled_drawStatus(sdInitError); 102 | break; 103 | case 3: 104 | oled_drawStatus(sdFull); 105 | break; 106 | case 4: 107 | oled_drawStatus(hex2bin); 108 | break; 109 | case 5: 110 | oled_drawStatus(bin2bmp); 111 | break; 112 | case 6: 113 | oled_drawStatus(bmp2png); 114 | break; 115 | case 7: 116 | oled_drawStatus(idlePrinter2); 117 | break; 118 | case 8: 119 | oled_drawStatus(forceFile); 120 | break; 121 | case 9: 122 | oled_drawStatus(idlePrinterServer); 123 | break; 124 | case 10: 125 | oled_drawStatus(bmp2bmp); 126 | break; 127 | case 11: 128 | oled_drawStatus(generateListFile); 129 | break; 130 | case 12: 131 | oled_drawStatus(Seeking_date_time); 132 | break; 133 | case 99: 134 | oled_drawStatus(oledTest); 135 | break; 136 | default: 137 | display.fillScreen(OLED_BLACK); 138 | break; 139 | } 140 | prevlcdStatus = lcdStatus; 141 | } 142 | } 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /NeoGB_Printer/zutil.c: -------------------------------------------------------------------------------- 1 | /* zutil.c -- target dependent utility functions for the compression library 2 | * Copyright (C) 1995-2017 Jean-loup Gailly 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "./includes/image/PNGenc/zutil.h" 9 | #ifndef Z_SOLO 10 | # include "./includes/image/PNGenc/gzguts.h" 11 | #endif 12 | 13 | z_const char * const z_errmsg[10] = { 14 | (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ 15 | (z_const char *)"stream end", /* Z_STREAM_END 1 */ 16 | (z_const char *)"", /* Z_OK 0 */ 17 | (z_const char *)"file error", /* Z_ERRNO (-1) */ 18 | (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ 19 | (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ 20 | (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ 21 | (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ 22 | (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ 23 | (z_const char *)"" 24 | }; 25 | 26 | 27 | const char * ZEXPORT zlibVersion() 28 | { 29 | return ZLIB_VERSION; 30 | } 31 | 32 | uLong ZEXPORT zlibCompileFlags() 33 | { 34 | uLong flags; 35 | 36 | flags = 0; 37 | switch ((int)(sizeof(uInt))) { 38 | case 2: break; 39 | case 4: flags += 1; break; 40 | case 8: flags += 2; break; 41 | default: flags += 3; 42 | } 43 | switch ((int)(sizeof(uLong))) { 44 | case 2: break; 45 | case 4: flags += 1 << 2; break; 46 | case 8: flags += 2 << 2; break; 47 | default: flags += 3 << 2; 48 | } 49 | switch ((int)(sizeof(voidpf))) { 50 | case 2: break; 51 | case 4: flags += 1 << 4; break; 52 | case 8: flags += 2 << 4; break; 53 | default: flags += 3 << 4; 54 | } 55 | switch ((int)(sizeof(z_off_t))) { 56 | case 2: break; 57 | case 4: flags += 1 << 6; break; 58 | case 8: flags += 2 << 6; break; 59 | default: flags += 3 << 6; 60 | } 61 | #ifdef ZLIB_DEBUG 62 | flags += 1 << 8; 63 | #endif 64 | #if defined(ASMV) || defined(ASMINF) 65 | flags += 1 << 9; 66 | #endif 67 | #ifdef ZLIB_WINAPI 68 | flags += 1 << 10; 69 | #endif 70 | #ifdef BUILDFIXED 71 | flags += 1 << 12; 72 | #endif 73 | #ifdef DYNAMIC_CRC_TABLE 74 | flags += 1 << 13; 75 | #endif 76 | #ifdef NO_GZCOMPRESS 77 | flags += 1L << 16; 78 | #endif 79 | #ifdef NO_GZIP 80 | flags += 1L << 17; 81 | #endif 82 | #ifdef PKZIP_BUG_WORKAROUND 83 | flags += 1L << 20; 84 | #endif 85 | #ifdef FASTEST 86 | flags += 1L << 21; 87 | #endif 88 | #if defined(STDC) || defined(Z_HAVE_STDARG_H) 89 | # ifdef NO_vsnprintf 90 | flags += 1L << 25; 91 | # ifdef HAS_vsprintf_void 92 | flags += 1L << 26; 93 | # endif 94 | # else 95 | # ifdef HAS_vsnprintf_void 96 | flags += 1L << 26; 97 | # endif 98 | # endif 99 | #else 100 | flags += 1L << 24; 101 | # ifdef NO_snprintf 102 | flags += 1L << 25; 103 | # ifdef HAS_sprintf_void 104 | flags += 1L << 26; 105 | # endif 106 | # else 107 | # ifdef HAS_snprintf_void 108 | flags += 1L << 26; 109 | # endif 110 | # endif 111 | #endif 112 | return flags; 113 | } 114 | 115 | #ifdef ZLIB_DEBUG 116 | #include 117 | # ifndef verbose 118 | # define verbose 0 119 | # endif 120 | int ZLIB_INTERNAL z_verbose = verbose; 121 | 122 | void ZLIB_INTERNAL z_error (m) 123 | char *m; 124 | { 125 | fprintf(stderr, "%s\n", m); 126 | exit(1); 127 | } 128 | #endif 129 | 130 | /* exported to allow conversion of error code to string for compress() and 131 | * uncompress() 132 | */ 133 | const char * ZEXPORT zError(err) 134 | int err; 135 | { 136 | return ERR_MSG(err); 137 | } 138 | 139 | #if defined(_WIN32_WCE) 140 | /* The Microsoft C Run-Time Library for Windows CE doesn't have 141 | * errno. We define it as a global variable to simplify porting. 142 | * Its value is always 0 and should not be used. 143 | */ 144 | int errno = 0; 145 | #endif 146 | 147 | #ifndef HAVE_MEMCPY 148 | 149 | void ZLIB_INTERNAL zmemcpy(dest, source, len) 150 | Bytef* dest; 151 | const Bytef* source; 152 | uInt len; 153 | { 154 | if (len == 0) return; 155 | do { 156 | *dest++ = *source++; /* ??? to be unrolled */ 157 | } while (--len != 0); 158 | } 159 | 160 | int ZLIB_INTERNAL zmemcmp(s1, s2, len) 161 | const Bytef* s1; 162 | const Bytef* s2; 163 | uInt len; 164 | { 165 | uInt j; 166 | 167 | for (j = 0; j < len; j++) { 168 | if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; 169 | } 170 | return 0; 171 | } 172 | 173 | void ZLIB_INTERNAL zmemzero(dest, len) 174 | Bytef* dest; 175 | uInt len; 176 | { 177 | if (len == 0) return; 178 | do { 179 | *dest++ = 0; /* ??? to be unrolled */ 180 | } while (--len != 0); 181 | } 182 | #endif 183 | 184 | #ifndef Z_SOLO 185 | 186 | #ifdef SYS16BIT 187 | 188 | #ifdef __TURBOC__ 189 | /* Turbo C in 16-bit mode */ 190 | 191 | # define MY_ZCALLOC 192 | 193 | /* Turbo C malloc() does not allow dynamic allocation of 64K bytes 194 | * and farmalloc(64K) returns a pointer with an offset of 8, so we 195 | * must fix the pointer. Warning: the pointer must be put back to its 196 | * original form in order to free it, use zcfree(). 197 | */ 198 | 199 | #define MAX_PTR 10 200 | /* 10*64K = 640K */ 201 | 202 | local int next_ptr = 0; 203 | 204 | typedef struct ptr_table_s { 205 | voidpf org_ptr; 206 | voidpf new_ptr; 207 | } ptr_table; 208 | 209 | local ptr_table table[MAX_PTR]; 210 | /* This table is used to remember the original form of pointers 211 | * to large buffers (64K). Such pointers are normalized with a zero offset. 212 | * Since MSDOS is not a preemptive multitasking OS, this table is not 213 | * protected from concurrent access. This hack doesn't work anyway on 214 | * a protected system like OS/2. Use Microsoft C instead. 215 | */ 216 | 217 | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) 218 | { 219 | voidpf buf; 220 | ulg bsize = (ulg)items*size; 221 | 222 | (void)opaque; 223 | 224 | /* If we allocate less than 65520 bytes, we assume that farmalloc 225 | * will return a usable pointer which doesn't have to be normalized. 226 | */ 227 | if (bsize < 65520L) { 228 | buf = farmalloc(bsize); 229 | if (*(ush*)&buf != 0) return buf; 230 | } else { 231 | buf = farmalloc(bsize + 16L); 232 | } 233 | if (buf == NULL || next_ptr >= MAX_PTR) return NULL; 234 | table[next_ptr].org_ptr = buf; 235 | 236 | /* Normalize the pointer to seg:0 */ 237 | *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; 238 | *(ush*)&buf = 0; 239 | table[next_ptr++].new_ptr = buf; 240 | return buf; 241 | } 242 | 243 | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) 244 | { 245 | int n; 246 | 247 | (void)opaque; 248 | 249 | if (*(ush*)&ptr != 0) { /* object < 64K */ 250 | farfree(ptr); 251 | return; 252 | } 253 | /* Find the original pointer */ 254 | for (n = 0; n < next_ptr; n++) { 255 | if (ptr != table[n].new_ptr) continue; 256 | 257 | farfree(table[n].org_ptr); 258 | while (++n < next_ptr) { 259 | table[n-1] = table[n]; 260 | } 261 | next_ptr--; 262 | return; 263 | } 264 | Assert(0, "zcfree: ptr not found"); 265 | } 266 | 267 | #endif /* __TURBOC__ */ 268 | 269 | 270 | #ifdef M_I86 271 | /* Microsoft C in 16-bit mode */ 272 | 273 | # define MY_ZCALLOC 274 | 275 | #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) 276 | # define _halloc halloc 277 | # define _hfree hfree 278 | #endif 279 | 280 | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) 281 | { 282 | (void)opaque; 283 | return _halloc((long)items, size); 284 | } 285 | 286 | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) 287 | { 288 | (void)opaque; 289 | _hfree(ptr); 290 | } 291 | 292 | #endif /* M_I86 */ 293 | 294 | #endif /* SYS16BIT */ 295 | 296 | 297 | #ifndef MY_ZCALLOC /* Any system without a special alloc function */ 298 | 299 | //#ifndef STDC 300 | //extern voidp malloc OF((uInt size)); 301 | //extern voidp calloc OF((uInt items, uInt size)); 302 | //extern void free OF((voidpf ptr)); 303 | //#endif 304 | 305 | //voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) 306 | // voidpf opaque; 307 | // unsigned items; 308 | // unsigned size; 309 | //{ 310 | // (void)opaque; 311 | // return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : 312 | // (voidpf)calloc(items, size); 313 | //} 314 | 315 | //void ZLIB_INTERNAL zcfree (opaque, ptr) 316 | // voidpf opaque; 317 | // voidpf ptr; 318 | //{ 319 | // (void)opaque; 320 | // free(ptr); 321 | //} 322 | 323 | #endif /* MY_ZCALLOC */ 324 | 325 | #endif /* !Z_SOLO */ 326 | -------------------------------------------------------------------------------- /NeoGB_Printer_PCB/ESP32_used.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer_PCB/ESP32_used.png -------------------------------------------------------------------------------- /NeoGB_Printer_PCB/EasyEDA Project/NeoGBP PCB.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer_PCB/EasyEDA Project/NeoGBP PCB.zip -------------------------------------------------------------------------------- /NeoGB_Printer_PCB/Gerber_Files_NeoGBP.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer_PCB/Gerber_Files_NeoGBP.zip -------------------------------------------------------------------------------- /NeoGB_Printer_PCB/NeoGBP_Schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/NeoGB_Printer_PCB/NeoGBP_Schematic.pdf -------------------------------------------------------------------------------- /NeoGB_Printer_PCB/README.md: -------------------------------------------------------------------------------- 1 | # Gameboy Printer Emulator - ESP32 PCB 2 | 3 | Buy Me A Coffee 4 | 5 | A simple PCB design using EasyEDA to work with this projects by me: 6 | * [NeoGB Printer](https://github.com/zenaro147/NeoGB-Printer) 7 | * [WiFi GBP Emulator - ESP32 Version](https://github.com/zenaro147/wifi-gbp-emulator/tree/feature/v3-esp32) 8 | 9 | [Order from OSH Park](https://oshpark.com/shared_projects/Y6LBKwvG) 10 | 11 | ## BOM list 12 | | Component | Where to buy | 13 | | --- | --- | 14 | | ESP32 Dev Board (38 pins, this [exact board](/NeoGB_Printer_PCB/ESP32_used.png)) | [AliExpress](https://www.aliexpress.com/item/1005001636295529.html) | 15 | | OLED Display 128x32 (0.91 inch) (optional) | [AliExpress](https://a.aliexpress.com/_mOHbftG) | 16 | | SD Card/MicroSD Card Module (Choose only one! I recommend the Standard SD module) | [AliExpress](https://fr.aliexpress.com/item/1005006059963950.html) | 17 | | 4 channel Logical Level Shifter (highly recommended) | [AliExpress](https://a.aliexpress.com/_m07pFpU) | 18 | | Female Pin Header with 40 pins (you need at least 38 pins, or 2 with 20pins) | [AliExpress](https://fr.aliexpress.com/item/4000873858801.html) | 19 | | PushButton 4.5x4.5mm (any height) - ONLY REV. 1 | [AliExpress](https://www.aliexpress.com/item/1005001629344310.html) | 20 | | PushButton 6x6mm (any height) - ONLY REV. 2 (still W.I.P.) | [AliExpress](https://fr.aliexpress.com/item/4000206046150.html) | 21 | | 5k or 10k resistor | [AliExpress](https://www.aliexpress.com/item/4001082088353.html) | 22 | | MicroUSB Female (optional, but mandatory if you want the charging module)| [AliExpress](https://www.aliexpress.com/item/4000385426649.html) | 23 | | Charging Module with StepUp (5V) - DD05CVSA (optional) | [AliExpress](https://www.aliexpress.com/item/33034500618.html) | 24 | | Micro Switch - SS-12D00G3 (optional, but mandatory if you want the charging module) | [AliExpress](https://www.aliexpress.com/item/1005003938856402.html) | 25 | | 2000mah Li-Po Battery (optional, but mandatory if you want the charging module) | [AliExpress](https://fr.aliexpress.com/item/1005002919536938.html) | 26 | | AGB Link Port Connector (optional) | [AliExpress](https://fr.aliexpress.com/item/1005006375410306.html) | 27 | | RGB LED 5mm (optional) | [AliExpress](https://www.aliexpress.com/item/1005002535018824.html) | 28 | | 220 Ohms resistor (if you want the LED) | [AliExpress](https://www.aliexpress.com/item/4001082088353.html) | 29 | 30 | ## How to build 31 | * First of all, solder the resistors, RGB led, button, the level shifter, USB port, and the female pin bar (oh, and the AGB link port, if you have one) 32 | * Put a little bit of in the RGB led jumper to bridge the middle pad to one of the other pads. (If you want a passthrough USB power, make bridge pads too) 33 | * Cut all remaining legs 34 | * Solder the SD/Micro SD module 35 | * Cut all remaining legs 36 | * Solder the male pin head for the charging module (but don't solder the module yet) 37 | * Cut all remaining legs 38 | * Solder the display and the battery 39 | * Cut all remaining legs 40 | * Solder the charging module into the pins 41 | 42 | I highly recommend to add some tape to prevent any unwanted contact between the modules (on SD/MicroSD, charging module and display to be more specific) and the solder points 43 | 44 | ## Inspirations/References 45 | * [Game Boy -related custom hardware by gekkio](https://github.com/Gekkio/gb-hardware) 46 | * [Game Boy WiFi Printer - D1 Mini Shield](https://github.com/cristofercruz/gbp-esp-shield-pcb) 47 | * [Gameboy Link Cable Breakout PCB](https://github.com/Palmr/gb-link-cable) 48 | 49 | ## External References 50 | * [ESP32-DEVKITC-32D](https://www.snapeda.com/parts/ESP32-DEVKITC-32D/Espressif%20Systems/view-part/) 51 | * [ESP32 Pinout](https://4.bp.blogspot.com/-nGLtB2nUrDg/Wp6DQbzcJMI/AAAAAAAABq0/A6Z46p0SQSEdERWocWL94oUmeATMQre4wCLcBGAs/s1600/3.png) 52 | * [ESP32 dev kit power options](https://techexplorations.com/guides/esp32/begin/power/) 53 | * [Power Supply for ESP32 with Battery Charger & Boost Converter](https://how2electronics.com/power-supply-for-esp32-with-boost-converter-battery-charger/#37V_to_5V_Step-Up_Boost_Converter_Module) 54 | * [ESP32 – Getting Battery charging level](https://www.pangodream.es/esp32-getting-battery-charging-level) 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The NeoGB Printer - ポケットプリンタエミュレータ 2 | 3 | Buy Me A Coffee 4 | 5 | The NeoGB Printer is a SD card-based standalone Game Boy Printer emulator. It is easy to build with parts readily available on the market. It does require little to no soldering skill and is fast to install from Arduino IDE (few dependancies). Using it is straigthforward and intuitive. Mounting the device with all parts on a table requires about an afternoon from opening the component bags to printing. 6 | 7 | This project is very similar to a popular ready-to-use solution available on the market, but the NeoGB Printer is open-source, cheap and tested with success with all officially released games (110 in total) that support the [original Gameboy Printer](https://en.wikipedia.org/wiki/Game_Boy_Printer). The total cost for all the parts bougth new is below $15. All parts can be easily exchanged with other projects, reused or harvested from dead electronics as they are all very common. 8 | 9 | You just need to upload the code using the Arduino IDE, connect the components like described here, plug your SD card and print any image directly from a Gameboy compatible game. Serial protocol is directly recorded under binary form on SD card. Once your printing session is finished, hold the [button](https://github.com/zenaro147/NeoGB-Printer/wiki/Hardware-Setup#push-button) for a few seconds and all the recorded data will be quickly converted to BMP and/or PNG images, ready to use with social media. Reboot the device once and you will access to an intuitive webserver mode. 10 | 11 | [**List of Games/Homebrew projects compatible with the NeoGB Printer**](https://github.com/zenaro147/NeoGB-Printer/wiki/Compatible-Games) 12 | 13 | ## How to build one? 14 | All the instructions can be found in our **Wiki Page** [![Wiki](https://img.shields.io/badge/docs-on%20Wiki-lightgrey)](https://github.com/zenaro147/NeoGB-Printer/wiki) 15 | 16 | ## Development Status 17 | Latest Stable Release [![Release Version](https://img.shields.io/github/v/release/zenaro147/NeoGB-Printer?style=plastic)](https://github.com/zenaro147/NeoGB-Printer/releases/latest/) [![Release Date](https://img.shields.io/github/release-date/zenaro147/NeoGB-Printer?style=plastic)](https://github.com/zenaro147/NeoGB-Printer/releases/latest/) 18 | 19 | Latest Development Release [![Release Version](https://img.shields.io/github/release/zenaro147/NeoGB-Printer/all.svg?style=plastic)](https://github.com/zenaro147/NeoGB-Printer/releases/) [![Release Date](https://img.shields.io/github/release-date-pre/zenaro147/NeoGB-Printer.svg?style=plastic)](https://github.com/zenaro147/NeoGB-Printer/releases/) 20 | 21 | Want a PCB for a cleaner design and easy to build? Check my [**PCB project here**](/NeoGB_Printer_PCB) ! 22 | 23 | If you still have questions, ask us here or in the **Game Boy Camera Club Discord** [![Discord Group](https://img.shields.io/badge/chat-on%20Discord-738ADB)](https://discord.gg/dKND7cFuqM) 24 | 25 | ## User manual in brief 26 | ![user_manual](/Supplementary_images/User_manual.png) 27 | 28 | ## Builds Showcases: 29 | ![My personal prototype build - zenaro147](/showcase/zenaro147.jpg) 30 | ![Setup by Raphaël BOICHOT](/showcase/RaphaelBOICHOT.jpg) 31 | ![Setup by Cristofer Cruz](/showcase/cristofercruz.jpg) 32 | 33 | ## Posts about: 34 | * [Hack a Day Article](https://hackaday.com/2021/10/22/an-open-source-game-boy-printer-that-doesnt-print/) 35 | * [Reddit post](https://www.reddit.com/r/Gameboy/comments/qdfoys/the_first_opensource_and_fully_standalone_game/) 36 | * [Distant Arcade - Blog post](https://distantarcade.co.uk/the-neogb-printer-game-boy-printer-emulator/) 37 | 38 | ## Authors contribution: 39 | * Rafael Zenaro: main code, hardware setting, new ideas, concept art, technical innovations and group facilitation. 40 | * Brian Khuu: architect of the Matrix, Game Boy Printer emulator core, BMP image decoder core. 41 | * Raphaël Boichot: code debugging, pixel perfect upscalers, blinking stuff support, hardcore gaming with Japanese kusoge. 42 | * Cristofer Cruz: 3D model for the GB Printer shell, code adaptation to LilyGo TTGO T2 Board. 43 | * Herr_Zatacke: support for the Game Boy Printer Web compatibility. 44 | 45 | Want to discuss with the authors or share your art and projects with people fond of the Game Boy Camera and Pocket Printer? [![Discord Group](https://img.shields.io/badge/chat-on%20Discord-738ADB)](https://discord.gg/dKND7cFuqM) 46 | 47 | ![credits](/Supplementary_images/credits.png) 48 | 49 | ## Based on existing projects: 50 | * [Mofosyne - Arduino Gameboy Printer Emulator](https://github.com/mofosyne/arduino-gameboy-printer-emulator) 51 | * [HerrZatacke - WiFi Game Boy Printer Emulator](https://github.com/HerrZatacke/wifi-gbp-emulator) 52 | * [Raphaël BOICHOT - Gameboy Printer Paper Simulation](https://github.com/Raphael-Boichot/GameboyPrinterPaperSimulation) 53 | -------------------------------------------------------------------------------- /Supplementary_images/LinkCable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Supplementary_images/LinkCable.jpg -------------------------------------------------------------------------------- /Supplementary_images/User_manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Supplementary_images/User_manual.png -------------------------------------------------------------------------------- /Supplementary_images/credits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/Supplementary_images/credits.png -------------------------------------------------------------------------------- /displayImages/128x32/1_splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/1_splashscreen.png -------------------------------------------------------------------------------- /displayImages/128x32/2_new_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/2_new_file.png -------------------------------------------------------------------------------- /displayImages/128x32/3_SD_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/3_SD_error.png -------------------------------------------------------------------------------- /displayImages/128x32/4_Building_webserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/4_Building_webserver.png -------------------------------------------------------------------------------- /displayImages/128x32/4_Printer_idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/4_Printer_idle.png -------------------------------------------------------------------------------- /displayImages/128x32/4_Printer_idle2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/4_Printer_idle2.png -------------------------------------------------------------------------------- /displayImages/128x32/4_Printer_webserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/4_Printer_webserver.png -------------------------------------------------------------------------------- /displayImages/128x32/4_Printer_webserver_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/4_Printer_webserver_2.jpg -------------------------------------------------------------------------------- /displayImages/128x32/5_SD_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/5_SD_full.png -------------------------------------------------------------------------------- /displayImages/128x32/6_bin2bmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/6_bin2bmp.png -------------------------------------------------------------------------------- /displayImages/128x32/6_bin2png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/6_bin2png.png -------------------------------------------------------------------------------- /displayImages/128x32/6_bmp2png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/6_bmp2png.png -------------------------------------------------------------------------------- /displayImages/128x32/6_bmpupscaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/6_bmpupscaling.png -------------------------------------------------------------------------------- /displayImages/128x32/6_txt2bmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/6_txt2bmp.png -------------------------------------------------------------------------------- /displayImages/128x32/6_txt2png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/6_txt2png.png -------------------------------------------------------------------------------- /displayImages/128x32/7_hex2bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/7_hex2bin.png -------------------------------------------------------------------------------- /displayImages/128x32/7_hex2txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/7_hex2txt.png -------------------------------------------------------------------------------- /displayImages/128x32/8_Seeking_date_time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/8_Seeking_date_time.png -------------------------------------------------------------------------------- /displayImages/128x32/upscaling_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/128x32/upscaling_image.png -------------------------------------------------------------------------------- /displayImages/96x64/1_splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/1_splashscreen.png -------------------------------------------------------------------------------- /displayImages/96x64/2_new_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/2_new_file.png -------------------------------------------------------------------------------- /displayImages/96x64/3_SD_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/3_SD_error.png -------------------------------------------------------------------------------- /displayImages/96x64/4_Building_webserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/4_Building_webserver.png -------------------------------------------------------------------------------- /displayImages/96x64/4_Printer_idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/4_Printer_idle.png -------------------------------------------------------------------------------- /displayImages/96x64/4_Printer_idle2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/4_Printer_idle2.png -------------------------------------------------------------------------------- /displayImages/96x64/4_Printer_webserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/4_Printer_webserver.png -------------------------------------------------------------------------------- /displayImages/96x64/4_Printer_webserver_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/4_Printer_webserver_2.png -------------------------------------------------------------------------------- /displayImages/96x64/5_SD_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/5_SD_full.png -------------------------------------------------------------------------------- /displayImages/96x64/6_bin2bmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/6_bin2bmp.png -------------------------------------------------------------------------------- /displayImages/96x64/6_bin2png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/6_bin2png.png -------------------------------------------------------------------------------- /displayImages/96x64/6_bmp2png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/6_bmp2png.png -------------------------------------------------------------------------------- /displayImages/96x64/6_bmpupscaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/6_bmpupscaling.png -------------------------------------------------------------------------------- /displayImages/96x64/6_txt2bmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/6_txt2bmp.png -------------------------------------------------------------------------------- /displayImages/96x64/6_txt2png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/6_txt2png.png -------------------------------------------------------------------------------- /displayImages/96x64/7_hex2bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/7_hex2bin.png -------------------------------------------------------------------------------- /displayImages/96x64/7_hex2txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/7_hex2txt.png -------------------------------------------------------------------------------- /displayImages/96x64/8_Seeking_date_time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/8_Seeking_date_time.png -------------------------------------------------------------------------------- /displayImages/96x64/upscaling_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/displayImages/96x64/upscaling_image.png -------------------------------------------------------------------------------- /showcase/RaphaelBOICHOT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/showcase/RaphaelBOICHOT.jpg -------------------------------------------------------------------------------- /showcase/cristofercruz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/showcase/cristofercruz.jpg -------------------------------------------------------------------------------- /showcase/zenaro147.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zenaro147/NeoGB-Printer/377ff011bf40a80bd2f198f5294db6bfd2cf0669/showcase/zenaro147.jpg --------------------------------------------------------------------------------