Emulator core geared towards emulating ZZT and Super ZZT.
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.

frontend_curses.c 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /**
  2. * Copyright (c) 2018 Adrian Siekierka
  3. *
  4. * This file is part of Zeta.
  5. *
  6. * Zeta is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Zeta is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Zeta. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <time.h>
  23. #include <ncurses.h>
  24. #include "zzt.h"
  25. long zeta_time_ms() {
  26. clock_t c = clock();
  27. return c / (CLOCKS_PER_SEC/1000);
  28. }
  29. void cpu_ext_log(const char* s) {
  30. fprintf(stderr, "%s\n", s);
  31. }
  32. void init_posix_vfs(const char* path);
  33. void speaker_on(double freq) {}
  34. void speaker_off() {}
  35. static int map_char_to_key[512];
  36. static WINDOW* window;
  37. int zeta_has_feature(int feature) {
  38. return 1;
  39. }
  40. static void platform_kbd_tick() {
  41. int c = getch();
  42. if (c == ERR) return;
  43. if (c == 263) c = 8;
  44. if (c == 0 || map_char_to_key[c] != 0) {
  45. int k = map_char_to_key[c];
  46. zzt_key(c, k);
  47. }
  48. }
  49. static void init_map_char_to_key() {
  50. map_char_to_key[258] = 0x50; // down
  51. map_char_to_key[260] = 0x4B; // left
  52. map_char_to_key[259] = 0x48; // up
  53. map_char_to_key[261] = 0x4D; // right
  54. map_char_to_key[13] = 0x1C; // enter
  55. map_char_to_key[0] = 0;
  56. map_char_to_key[0x1C] = 1; // esc
  57. for (int i = 1; i <= 9; i++) map_char_to_key[i + 48] = i + 1;
  58. char* chrs = "!@#$%^&*()";
  59. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = i + 1;
  60. map_char_to_key[48] = 11; // numbers
  61. map_char_to_key[45] = 12; // -
  62. map_char_to_key[95] = 12; // _
  63. map_char_to_key[61] = 13; // =
  64. map_char_to_key[43] = 12; // +
  65. map_char_to_key[8] = 14; // backspace
  66. map_char_to_key[9] = 15; // tab
  67. chrs = "qwertyuiop[]";
  68. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = 15 + i;
  69. chrs = "QWERTYUIOP{}";
  70. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = 15 + i;
  71. map_char_to_key[13] = 28; // enter
  72. // 29?
  73. chrs = "asdfghjkl;'";
  74. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = 29 + i;
  75. chrs = "ASDFGHJKL:\"";
  76. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = 29 + i;
  77. map_char_to_key[96] = 41; // `
  78. map_char_to_key[126] = 41; // ~
  79. // 42?
  80. map_char_to_key[92] = 43;
  81. map_char_to_key[124] = 43; // |
  82. chrs = "zxcvbnm,./";
  83. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = 43 + i;
  84. chrs = "ZXCVBNM<>?";
  85. for (int i = 0; i < strlen(chrs); i++) map_char_to_key[(int)chrs[i]] = 43 + i;
  86. // 54?
  87. map_char_to_key[42] = 55; // *
  88. // 56?
  89. map_char_to_key[32] = 57; // space
  90. }
  91. int main(int argc, char** argv) {
  92. init_posix_vfs("vfs/");
  93. init_map_char_to_key();
  94. zzt_init();
  95. window = initscr();
  96. cbreak();
  97. noecho();
  98. nonl();
  99. wclear(window);
  100. nodelay(window, 1);
  101. scrollok(window, 1);
  102. idlok(window, 1);
  103. keypad(window, 1);
  104. clock_t last = clock();
  105. clock_t curr = last;
  106. while (zzt_execute(1600000)) {
  107. // refresh screen
  108. u8* ram = zzt_get_ram();
  109. for (int y = 0; y < 25; y++) {
  110. for (int x = 0; x < 80; x++) {
  111. u8 chr = ram[TEXT_ADDR(x,y)];
  112. if (chr == 2) chr = '@';
  113. else if (chr == 0) chr = 32;
  114. else if (chr < 32 || chr >= 128)
  115. chr = '0' + (chr % 10);
  116. mvwaddch(window, y, x, chr);
  117. }
  118. }
  119. wrefresh(window);
  120. zzt_mark_frame();
  121. curr = clock();
  122. float secs = (float) (curr - last) / CLOCKS_PER_SEC;
  123. fprintf(stderr, "%.2f opc/sec\n", 1600000.0f / secs);
  124. platform_kbd_tick();
  125. last = curr;
  126. zzt_mark_timer();
  127. }
  128. }