Collaborative ASCII art https://ascii.town
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.4KB

  1. /*
  2. * Copyright (c) 2017, Curtis McEnroe <curtis@cmcenroe.me>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Affero General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Affero General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <curses.h>
  18. #include <err.h>
  19. #include <fcntl.h>
  20. #include <stdio.h>
  21. #include <sysexits.h>
  22. #include <unistd.h>
  23. #undef COLOR_BLACK
  24. #undef COLOR_RED
  25. #undef COLOR_GREEN
  26. #undef COLOR_YELLOW
  27. #undef COLOR_BLUE
  28. #undef COLOR_MAGENTA
  29. #undef COLOR_CYAN
  30. #undef COLOR_WHITE
  31. #include "torus.h"
  32. static ssize_t writeAll(int fd, const char *buf, size_t len) {
  33. ssize_t writeLen;
  34. while (0 < (writeLen = write(fd, buf, len))) {
  35. buf += writeLen;
  36. len -= writeLen;
  37. }
  38. return writeLen;
  39. }
  40. static void drawTile(int offsetY, const struct Tile *tile) {
  41. for (int y = 0; y < CELL_ROWS; ++y) {
  42. for (int x = 0; x < CELL_COLS; ++x) {
  43. uint8_t color = tile->colors[y][x];
  44. char cell = tile->cells[y][x];
  45. int attrs = COLOR_PAIR(color & ~COLOR_BRIGHT);
  46. if (color & COLOR_BRIGHT) attrs |= A_BOLD;
  47. mvaddch(offsetY + y, x, attrs | cell);
  48. }
  49. }
  50. }
  51. int main(int argc, char *argv[]) {
  52. if (argc != 4) return EX_USAGE;
  53. int fileA = open(argv[1], O_RDONLY);
  54. if (fileA < 0) err(EX_IOERR, "%s", argv[1]);
  55. int fileB = open(argv[2], O_RDONLY);
  56. if (fileB < 0) err(EX_IOERR, "%s", argv[2]);
  57. int fileC = open(argv[3], O_WRONLY | O_CREAT, 0644);
  58. if (fileC < 0) err(EX_IOERR, "%s", argv[3]);
  59. initscr();
  60. cbreak();
  61. noecho();
  62. keypad(stdscr, true);
  63. set_escdelay(100);
  64. start_color();
  65. for (int bg = COLOR_BLACK; bg < COLOR_BRIGHT; ++bg) {
  66. for (int fg = COLOR_BLACK; fg < COLOR_BRIGHT; ++fg) {
  67. init_pair(bg << 4 | fg, fg, bg);
  68. }
  69. }
  70. mvhline(CELL_ROWS, 0, 0, CELL_COLS);
  71. mvhline(CELL_ROWS * 2 + 1, 0, 0, CELL_COLS);
  72. mvvline(0, CELL_COLS, 0, CELL_ROWS * 2 + 1);
  73. mvaddch(CELL_ROWS, CELL_COLS, ACS_RTEE);
  74. mvaddch(CELL_ROWS * 2 + 1, CELL_COLS, ACS_LRCORNER);
  75. struct Tile tileA, tileB;
  76. for (;;) {
  77. ssize_t lenA = read(fileA, &tileA, sizeof(tileA));
  78. if (lenA < 0) err(EX_IOERR, "%s", argv[1]);
  79. ssize_t lenB = read(fileB, &tileB, sizeof(tileB));
  80. if (lenB < 0) err(EX_IOERR, "%s", argv[2]);
  81. if (!lenA && !lenB) break;
  82. if (!lenA || !lenB) errx(EX_IOERR, "different size inputs");
  83. const struct Tile *tileC = (tileA.access > tileB.access) ? &tileA : &tileB;
  84. if (tileA.modify != tileB.modify) {
  85. drawTile(0, &tileA);
  86. drawTile(CELL_ROWS + 1, &tileB);
  87. move(CELL_ROWS * 2 + 2, 0);
  88. refresh();
  89. int c;
  90. do { c = getch(); } while (c != 'a' && c != 'b');
  91. tileC = (c == 'a') ? &tileA : &tileB;
  92. }
  93. ssize_t lenC = writeAll(fileC, (char *)tileC, sizeof(*tileC));
  94. if (lenC < 0) err(EX_IOERR, "%s", argv[3]);
  95. }
  96. endwin();
  97. return EX_OK;
  98. }