]> git.sur5r.net Git - c128-kasse/commitdiff
Merge pull request #15 from 9b17fe/refactor
authorMaik Fischer <maikf+github@qu.cx>
Mon, 30 Oct 2017 13:03:29 +0000 (14:03 +0100)
committerGitHub <noreply@github.com>
Mon, 30 Oct 2017 13:03:29 +0000 (14:03 +0100)
Refactor the codebase

21 files changed:
.clang_complete [new file with mode: 0644]
.dir-locals.el [new file with mode: 0644]
.gitignore
Makefile
include/c128time.h
include/config.h
include/credit_manager.h
include/general.h
include/globals.h [new file with mode: 0644]
include/kasse.h
include/print.h
include/vdc_patch_charset.h
include/vdc_util.h
src/config.c
src/credit_manager.c
src/general.c
src/globals.c [new file with mode: 0644]
src/itemz.c
src/kasse.c
src/print.c
test/test.c

diff --git a/.clang_complete b/.clang_complete
new file mode 100644 (file)
index 0000000..5c112e1
--- /dev/null
@@ -0,0 +1,5 @@
+-I/usr/share/cc65/include
+-Iinclude
+-nostdlibinc
+-nobuiltininc
+-D__fastcall__=''
diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644 (file)
index 0000000..2cdd487
--- /dev/null
@@ -0,0 +1,5 @@
+((nil . ())
+ (c-mode . ((c-basic-offset . 2)
+            (indent-tabs-mode . nil)
+            (flycheck-clang-include-path . ("/usr/share/cc65/include"))
+            (flycheck-clang-language-standard . "c99"))))
index a45be6e9ffd1798a931462347051ebaf16ec0a89..c5eb3a49595b962c123f54cb3b9bb6d065105828 100644 (file)
@@ -4,7 +4,7 @@ kasse
 build/
 *.P00
 itemz
-*.d64
+*.d71
 include/version.h
 include/charset_umlauts.h
 tags
@@ -14,3 +14,5 @@ cat
 charmap
 ascii
 *.lbl
+TAGS
+test/test
index 1df105e47f6445f124df0ea960ae096f60f564eb..bf11dd85cc130a6a4234aa4aacffd2f56aefbd14 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,13 @@ build/%.o: src/%.c ${INCLUDES}
 build/%.o: src/%.s
        ${AS} ${CFLAGS} $< -o $@
 
+build/%.o: test/%.c ${INCLUDES}
+       ${CC} ${CFLAGS} -O $< -o build/$(addsuffix .s,$(shell basename $< .c))
+       ${AS} ${CFLAGS} build/$(addsuffix .s,$(shell basename $< .c)) -o $@
+
+build/%.o: test/%.s
+       ${AS} ${CFLAGS} $< -o $@
+
 include/version.h:
        mkdir -p build
        echo "#define GV \"${GV}\"" > $@
@@ -23,13 +30,13 @@ include/version.h:
 include/charset_umlauts.h:
        ./util/mkfont assets/umlauts.pbm chars_umlauts > $@
 
-kasse: build/config.o build/kasse.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/vdc_patch_charset.o build/vdc_util.o
+kasse: build/config.o build/kasse.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/vdc_patch_charset.o build/vdc_util.o build/globals.o
        ${LD} -Ln $@.lbl -t c128 $^ -o $@
 
-itemz: build/config.o build/itemz.o build/general.o build/credit_manager.o build/c128time.o build/print.o
+itemz: build/config.o build/itemz.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/globals.o
        ${LD} -Ln $@.lbl -t c128 $^ -o $@
 
-cat: build/general.o build/cat.o
+cat: build/general.o build/cat.o build/config.o build/print.o build/globals.o
        ${LD} -Ln $@.lbl -t c128 $^ -o $@
 
 charmap: build/print_charmap.o build/vdc_util.o build/vdc_patch_charset.o
@@ -39,26 +46,26 @@ ascii: build/print_ascii.o
        ${LD} -Ln $@.lbl -t c128 $^ -o $@
 
 package: all
-       c1541 -format "${GV}",KA d64 kasse.d64
-       c1541 -attach kasse.d64 -write kasse
-       c1541 -attach kasse.d64 -write itemz
-       [ -e state ] && c1541 -attach kasse.d64 -write state || exit 0
-       [ -e items ] && c1541 -attach kasse.d64 -write items || exit 0
+       c1541 -format "${GV}",KA d71 kasse.d71
+       c1541 -attach kasse.d71 -write kasse
+       c1541 -attach kasse.d71 -write itemz
+       [ -e state ] && c1541 -attach kasse.d71 -write state || exit 0
+       [ -e items ] && c1541 -attach kasse.d71 -write items || exit 0
 
-test: build/config.o test/test.o build/general.o
-       cl65 -t c128 $^ -o build/test
+test: build/config.o build/test.o build/general.o build/print.o build/globals.o
+       ${LD} -Ln $@.lbl -t c128 $^ -o test/$@
 
 test-package: test
-       c1541 -format "test",TE d64 test.d64
-       c1541 -attach test.d64 -write test || exit 0
-       c1541 -attach test.d64 -write state || exit 0
-       c1541 -attach test.d64 -write items || exit 0
+       c1541 -format "test",TE d71 test.d71
+       c1541 -attach test.d71 -write test/test || exit 0
+       c1541 -attach test.d71 -write state || exit 0
+       c1541 -attach test.d71 -write items || exit 0
 
 clean:
-       rm -rf build/*.o build/*.s test/*.o test/*.s
+       rm -rf build/*.o build/*.s test/test
 
 dist-clean: clean
-       rm -f kasse kasse.lbl itemz itemz.lbl cat cat.lbl kasse.d64
+       rm -f kasse kasse.lbl itemz itemz.lbl cat cat.lbl kasse.d71
 
 format:
        clang-format-3.9 -i **/*.[ch]
index a53d2688d52dec8c9a875e54703cb596f2be96dd..c59528030579bcbe4688c96fad956691e2e24fc3 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef TIME_H_
-#define TIME_H_
+#ifndef TIME_H
+#define TIME_H
 void set_time(BYTE hrs, BYTE min, BYTE sec);
 char *get_time(void);
 #endif
index 5a19e804afe7020931f0bb75979a74b242505b76..4dd7fcc9f71f0bfe93cb6e41121060352503611f 100644 (file)
@@ -1,7 +1,7 @@
 #include "general.h"
 
-#ifndef CONFIG_H_
-#define CONFIG_H_
+#ifndef CONFIG_H
+#define CONFIG_H
 
 #define MAX_ITEMS 32
 #define MAX_ITEM_NAME_LENGTH 9
@@ -41,7 +41,7 @@ struct credits_array_t {
   struct credits_t credits[MAX_CREDIT_ITEMS];
 };
 
-#ifndef _IS_CONFIG_C
+#ifndef IS_CONFIG_C
 extern struct status_array_t status;
 extern struct credits_array_t credits;
 #endif
@@ -54,4 +54,4 @@ void load_credits(void);
 
 void save_items(void);
 void save_credits(void);
-#endif /*CONFIG_H_*/
+#endif /* CONFIG_H */
index dba26c777870bc02bec16040c046f854f10063e3..79a4a57047d5409893a8de82f95e318eeaa0d368 100644 (file)
@@ -1,6 +1,8 @@
-#ifndef CREDIT_MANAGER_H_
-#define CREDIT_MANAGER_H_
+#ifndef CREDIT_MANAGER_H
+#define CREDIT_MANAGER_H
+
 struct credits_t *find_credit(char *name);
 void deposit_credit(char *input);
 void credit_manager(void);
-#endif
+
+#endif /* CREDIT_MANAGER_H */
index 716ee392f0950fa68756888b60a6655eabefae03..df02244841ac1a03c13c3c0ab11296295c2403df 100644 (file)
@@ -1,7 +1,9 @@
-#ifndef GENERAL_H_
-#define GENERAL_H_
+#ifndef GENERAL_H
+#define GENERAL_H
 
 #include <peekpoke.h>
+#include <stdint.h>
+#include "vdc_patch_charset.h"
 
 typedef unsigned char BYTE;
 typedef enum {
@@ -12,6 +14,10 @@ typedef input_terminator_t input_terminator_mask_t;
 input_terminator_t get_input_terminated_by(input_terminator_mask_t terminators,
                                            char *out, BYTE outlen);
 char *get_input(void);
+BYTE cgetn_input(char *s, BYTE len);
+int16_t cget_number(int16_t default_val);
+void cget_return(void);
+uint8_t cget_nickname(char *buf, uint8_t len);
 char retry_or_quit(void);
 char *format_euro(char *s, int maxlen, int cent);
 void c128_perror(BYTE, char *);
@@ -43,6 +49,8 @@ extern BYTE _oserror;
 #define PETSCII_CR 13
 /* Delete */
 #define PETSCII_DEL 20
+/* Escape */
+#define PETSCII_ESC 27
 /* Space */
 #define PETSCII_SP 32
 #define PETSCII_0 48
@@ -58,6 +66,9 @@ extern BYTE _oserror;
 
 #define VIDEOMODE (((*(BYTE *)0xD7) == 0x80) ? 80 : 40)
 
+#define EUR_FORMAT "%3d,%02d" EURSYM
+#define EUR_FORMAT_MINLEN (sizeof("999,99" EURSYM) + 1)
+
 /* because there is no macro expansion when stringifying, we need to use two
  * levels of macros to stringify the value of a macro (for example
  * MAX_ITEM_NAME_LENGTH) */
@@ -67,4 +78,4 @@ extern BYTE _oserror;
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) > (b) ? (b) : (a))
 
-#endif /*GENERAL_H_*/
+#endif /* GENERAL_H */
diff --git a/include/globals.h b/include/globals.h
new file mode 100644 (file)
index 0000000..8a64063
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include <stdint.h>
+
+#ifdef IS_GLOBALS_C
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+void init_globals(void);
+
+GLOBAL uint8_t printing;
+
+#endif /*  GLOBALS_H */
index 93650f368f7c3ab92a681a01a0e59f2ab402ee8c..aac65da91fb2ac3d1493e271692d15fff1a799d7 100644 (file)
@@ -1,9 +1,6 @@
-#ifndef _KASSE_H
-#define _KASSE_H
+#ifndef KASSE_H
+#define KASSE_H
 
 void print_the_buffer(void);
 
-#ifdef _IS_KASSE
-BYTE printing = 1;
-#endif
 #endif
index 78d65d0fbc7db9708d8a8d0dffe7841af7b0379e..990e4df3694904bacca19294b70a92728b029cd1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _PRINT_H
-#define _PRINT_H
+#ifndef PRINT_H
+#define PRINT_H
 
 void init_log(void);
 void print_the_buffer(void);
@@ -7,7 +7,7 @@ void print_header(void);
 void log_file(const char *s);
 void log_flush(void);
 
-#ifdef _IS_PRINT
+#ifdef IS_PRINT_C
 char print_buffer[80 + 2 + 1];
 unsigned char log_num = 0;
 #else
index ff80c82ef3f6d83f7ece5f06337af561a094121c..8b26b4857ec511004a5eba142cfd07de26071bc7 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __VDC_PATCH_CHARSET_H_
-#define __VDC_PATCH_CHARSET_H_
+#ifndef VDC_PATCH_CHARSET_H
+#define VDC_PATCH_CHARSET_H
 
 void vdc_patch_charset(void);
 
@@ -12,4 +12,4 @@ void vdc_patch_charset(void);
 #define uUML "\xA9"
 #define szLIG "\xBF"
 
-#endif // __VDC_PATCH_CHARSET_H_
+#endif /* VDC_PATCH_CHARSET_H */
index 2c10ccd5f761161b00020966001d292ba9fb27aa..84c6e00021e55828f41cb73938331a92ea02b8f6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __VDC_UTIL_H_
-#define __VDC_UTIL_H_
+#ifndef VDC_UTIL_H
+#define VDC_UTIL_H
 
 extern void __fastcall__ vdc_load_thinfont(void);
 extern unsigned char __fastcall__ vdc_read_reg(unsigned char reg);
@@ -11,4 +11,4 @@ extern void __fastcall__ vdc_write_mem(unsigned dest, const void *src,
                                        unsigned n);
 extern void __fastcall__ vdc_load_thinfont(void);
 
-#endif // __VDC_UTIL_H_
+#endif /* VDC_UTIL_H */
index 6f561248a473743c9fb0dfcdd237b8cb5a59f1c6..6d447a740e8e0385bbe24729fe24f6a35a4b001d 100644 (file)
@@ -4,7 +4,7 @@
  * See LICENSE for license information
  *
  */
-#define _IS_CONFIG_C
+#define IS_CONFIG_C
 
 #include <stdlib.h>
 #include <conio.h>
index 347326a28fd2331e68cebe9da407e87919cffd4a..7aa4724536c1216d884352ff825f0e4b69fccf23 100644 (file)
@@ -24,7 +24,7 @@ static BYTE current_credits_page = 0;
 
 static void credit_print_screen(void) {
   BYTE i, pages;
-  char buffer[10];
+  char buffer[EUR_FORMAT_MINLEN];
 
   clrscr();
   cprintf("credit_manager (phil_fry, sECuRE, sur5r) v:" GV "\r\n\r\n");
@@ -39,7 +39,8 @@ static void credit_print_screen(void) {
        i++) {
     if (filter == NULL ||
         strncmp(credits.credits[i].nickname, filter, filter_len) == 0) {
-      if (format_euro(buffer, 10, credits.credits[i].credit) != buffer) {
+      if (format_euro(buffer, sizeof(buffer), credits.credits[i].credit) !=
+          buffer) {
         cprintf("Error: Could not format credit %d\r\n",
                 credits.credits[i].credit);
         exit(1);
@@ -61,58 +62,44 @@ struct credits_t *find_credit(char *name) {
   return NULL;
 }
 
-/*
- * Deposits credit for a user. Called in the credit manager (with input ==
- * NULL) or interactively when the user does not have enough money for his
- * intended purchase (with input == nickname).
- *
- */
-void deposit_credit(char *input) {
+void deposit_credit(char *nickname) {
   char *time = get_time();
   struct credits_t *credit;
   unsigned int deposit;
 
-  if (input == NULL) {
-    cprintf("\r\nName:\r\n");
-    if ((input = get_input()) == NULL || *input == '\0')
-      return; // no name given
-  }
-
-  if ((credit = find_credit(input)) == NULL)
+  if ((credit = find_credit(nickname)) == NULL)
     return; // cannot find named credit
 
   cprintf("\r\nEinzahlung in Cent:\r\n");
-  if ((input = get_input()) == NULL || *input == '\0' ||
-      (deposit = atoi(input)) == 0)
+  if (cget_number(0) == 0)
     return;
 
   credit->credit += deposit;
 
   print_the_buffer();
   cprintf("\r\nEinzahlung durchgef" uUML "hrt, dr" uUML "cke RETURN...\r\n");
-  input = get_input();
+  cget_return();
 }
 
 static void new_credit(void) {
-  char *input, *name;
+  char name[NICKNAME_MAX_LEN + 1];
   char *time;
   int credit;
 
-  if (credits.num_items == 75) {
+  if (credits.num_items == MAX_CREDIT_ITEMS) {
     cprintf("\rEs ist bereits die maximale Anzahl an Eintr" aUML
             "gen erreicht, dr" uUML "cke RETURN...\r\n");
-    input = get_input();
+    cget_return();
     return;
   }
 
   clrscr();
   cprintf("\rNickname (max. 10 Zeichen):\r\n");
-  if ((input = get_input()) == NULL || *input == '\0')
+  if (cgetn_input(name, sizeof(name)) == 0)
     return;
-  name = strdup(input);
+
   cprintf("\r\nGuthaben in Cents:\r\n");
-  if ((input = get_input()) == NULL || *input == '\0' ||
-      (credit = atoi(input)) == 0)
+  if ((credit = cget_number(0)) == 0)
     return;
   strncpy(credits.credits[credits.num_items].nickname, name, NICKNAME_MAX_LEN);
   credits.credits[credits.num_items].credit = credit;
@@ -127,7 +114,7 @@ static void new_credit(void) {
 }
 
 static void _delete_credit(BYTE num) {
-  memset(credits.credits[num].nickname, '\0', 11);
+  memset(credits.credits[num].nickname, '\0', NICKNAME_MAX_LEN + 1);
   credits.credits[num].credit = 0;
 }
 
@@ -142,7 +129,8 @@ static void delete_credit(void) {
   if (credits.num_items > 1) {
     /* Swap last item with this one and delete the last one to avoid holes */
     last = (credits.num_items - 1);
-    strcpy(credits.credits[num].nickname, credits.credits[last].nickname);
+    strncpy(credits.credits[num].nickname, credits.credits[last].nickname,
+            NICKNAME_MAX_LEN);
     credits.credits[num].credit = credits.credits[last].credit;
     _delete_credit(last);
   } else {
@@ -153,6 +141,7 @@ static void delete_credit(void) {
 }
 
 void credit_manager() {
+  char nickname[NICKNAME_MAX_LEN + 1];
   char *c;
   while (1) {
     credit_print_screen();
@@ -176,12 +165,15 @@ void credit_manager() {
         current_credits_page--;
       break;
     case 'p':
-      deposit_credit(NULL);
+      cputs("\rName?\r\n");
+      if (cgetn_input(nickname, sizeof(nickname)))
+        deposit_credit(nickname);
       break;
     case 'g':
       cprintf("Filter eingeben:\r\n");
       filter = get_input();
-      if (filter == NULL || *filter == 32 || (filter_len = strlen(filter)) == 0)
+      if (filter == NULL || *filter == PETSCII_SP ||
+          (filter_len = strlen(filter)) == 0)
         filter = NULL;
       break;
     case 'z':
@@ -189,7 +181,7 @@ void credit_manager() {
       return;
     default:
       cprintf("Unbekannter Befehl, dr" uUML "cke RETURN...\r\n");
-      get_input();
+      cget_return();
     }
   }
 }
index ec06ef4271349565a27ad29c03899d77e6e01783..a036603613b0c1ba482f790c825051b3346ed1bd 100644 (file)
@@ -8,8 +8,10 @@
 #include <stdio.h>
 #include <string.h>
 #include <conio.h>
+#include <stdint.h>
 
 #include "general.h"
+#include "config.h"
 #include "vdc_patch_charset.h"
 
 /*
@@ -66,6 +68,144 @@ char *get_input(void) {
   return output;
 }
 
+BYTE cgetn_input(char *s, BYTE len) {
+  memset(s, '\0', len);
+  get_input_terminated_by(INPUT_TERMINATOR_RETURN, s, len);
+  return strlen(s);
+}
+
+int16_t cget_number(int16_t default_val) {
+  char c;
+  int x, y;
+  uint8_t num_chars = 0;
+  char buf[6] = {0, 0, 0, 0, 0, 0};
+  int i = 0;
+  x = wherex();
+  y = wherey();
+  while (1) {
+    c = cgetc();
+
+    /* Enter */
+    if (c == PETSCII_CR)
+      break;
+
+    /* Backspace */
+    if (c == PETSCII_DEL) {
+      if (i == 0)
+        continue;
+      buf[--i] = '\0';
+      cputcxy(x + i, y, ' ');
+      gotoxy(x + i, y);
+      continue;
+    }
+
+    /* Abort */
+    if (c == PETSCII_ESC) {
+      return default_val;
+    }
+
+    /* end of buffer? wait for user to press RETURN */
+    if (i == (sizeof(buf) - 1))
+      continue;
+
+    /* match either numbers or iff it's the first entered char a minus sign */
+    if ((c >= PETSCII_0 && c <= PETSCII_9) || (c == '-' && i == 0)) {
+      buf[i] = c;
+      ++i;
+      ++num_chars;
+      cputc(c);
+    }
+  }
+
+  if (num_chars == 0) {
+    return default_val;
+  } else if ((num_chars == 1) && (c == '-')) {
+    return default_val;
+  }
+
+  return atoi(buf);
+}
+
+uint8_t cget_nickname(char *nickname, uint8_t length) {
+  uint8_t i, x, y, matches;
+  char *uniquematch;
+  input_terminator_t terminator;
+
+  memset(nickname, '\0', length);
+
+  while (1) {
+    terminator = get_input_terminated_by(
+        INPUT_TERMINATOR_RETURN | INPUT_TERMINATOR_SPACE, nickname, length);
+
+    /* Clear the screen from any previous completions */
+    x = wherex();
+    y = wherey();
+    for (i = 1; i < 7; i++) {
+      /* "Completion:" is longer than NICKNAME_MAX_LEN */
+      cclearxy(0, y + i, strlen("Completion:"));
+    }
+    gotoxy(x, y);
+
+    if (terminator != INPUT_TERMINATOR_SPACE) {
+      return strlen(nickname);
+    }
+
+    matches = 0;
+    uniquematch = NULL;
+    for (i = 0; i < credits.num_items; i++) {
+      if (strncmp(nickname, credits.credits[i].nickname, strlen(nickname)) !=
+          0) {
+        continue;
+      }
+      matches++;
+      if (matches > 1) {
+        break;
+      }
+      uniquematch = credits.credits[i].nickname;
+    }
+    if (matches == 1) {
+      /* Display the rest of the nickname */
+      textcolor(TC_LIGHT_GREEN);
+      cprintf("%s", uniquematch + strlen(nickname));
+      textcolor(TC_LIGHT_GRAY);
+      strcat(nickname, uniquematch + strlen(nickname));
+    } else {
+      /* Multiple nicknames match what was entered so far. Abort and
+       * display all matches, then prompt the user again. */
+      char completion[NICKNAME_MAX_LEN + 1];
+      BYTE len = strlen(nickname);
+      x = wherex();
+      y = wherey();
+      cprintf("\r\nCompletion:\r\n");
+      matches = 0;
+      for (i = 0; i < credits.num_items; i++) {
+        if (strncmp(nickname, credits.credits[i].nickname, len) != 0) {
+          continue;
+        }
+        if (++matches == 5) {
+          cprintf("...\r\n");
+          break;
+        }
+        strcpy(completion, credits.credits[i].nickname);
+        *(completion + len) = '\0';
+        cprintf("%s", completion);
+        textcolor(TC_LIGHT_GREEN);
+        cprintf("%c", *(credits.credits[i].nickname + len));
+        textcolor(TC_LIGHT_GRAY);
+        cprintf("%s\r\n", completion + len + 1);
+      }
+      gotoxy(x, y);
+    }
+  }
+}
+
+/* wait until user pressed RETURN, ignore all other input */
+void cget_return() {
+  while (cgetc() != PETSCII_CR) {
+  }
+  return;
+}
+
 char retry_or_quit(void) {
   char *c;
   do {
@@ -76,7 +216,7 @@ char retry_or_quit(void) {
 }
 
 char *format_euro(char *s, int maxlen, int cent) {
-  if (snprintf(s, maxlen, "%3d,%02d" EURSYM, cent / 100, cent % 100) > maxlen)
+  if (snprintf(s, maxlen, EUR_FORMAT, cent / 100, cent % 100) > maxlen)
     return NULL;
   return s;
 }
diff --git a/src/globals.c b/src/globals.c
new file mode 100644 (file)
index 0000000..c1032e2
--- /dev/null
@@ -0,0 +1,7 @@
+#define IS_GLOBALS_C
+#include "globals.h"
+
+void init_globals(void) {
+  printing = 1;
+  return;
+}
index f04678c0753f1801a6b9a5d5470c18bf0db7f3c0..7cf8ea6d6acba579876ea9c9c0c6adf6abfbb050 100644 (file)
 #include "config.h"
 #include "credit_manager.h"
 #include "version.h"
+#include "vdc_patch_charset.h"
+#include "globals.h"
 
 static void itemz_print_screen(void) {
   BYTE i;
-  char buffer[10];
+  char buffer[EUR_FORMAT_MINLEN];
 
   clrscr();
-  cprintf("itemz (phil_fry, sECuRE, sur5r) v:" GV "\r\n\r\n");
+  cprintf("itemz (phil_fry, sECuRE, sur5r, mxf) v:" GV "\r\n\r\n");
   cprintf("Datei: ITEMS\r\n\r\n");
   for (i = 0; i < max(status.num_items, 15); i++) {
-    if (format_euro(buffer, 10, status.status[i].price) != buffer) {
+    if (format_euro(buffer, sizeof(buffer), status.status[i].price) != buffer) {
       cprintf("Error: Could not format price %d\r\n", status.status[i].price);
       exit(1);
     }
     cprintf("Eintrag %2d: %s (%s, %d mal verkauft)\r\n", i,
             status.status[i].item_name, buffer, status.status[i].times_sold);
   }
-  cprintf("\r\nn) Neu d) Loeschen s) Speichern m) Credit Modus q) "
-          "Beenden\r\nr) Reset des Verkauft-Zaehlers\r\n");
+  cprintf("\r\nn) Neu d) L" oUML "schen s) Speichern m) Credit Modus q) "
+          "Beenden\r\nr) Reset des Verkauft-Z" aUML "hlers\r\n");
 }
 
 static void new_item(void) {
-  char *input, *name;
-  int price;
+  char name[MAX_ITEM_NAME_LENGTH + 1];
+  int price, times_sold;
 
   if (status.num_items == MAX_ITEMS) {
-    cprintf("\rEs ist bereits die maximale Anzahl an Eintraegen erreicht, "
-            "druecke RETURN...\r\n");
-    input = get_input();
+    cprintf("\rEs ist bereits die maximale Anzahl an Eintr" aUML
+            "gen erreicht, dr" uUML "cke RETURN...\r\n");
+    cget_return();
     return;
   }
 
   cprintf("\rName des Eintrags:\r\n");
-  if ((input = get_input()) == NULL || *input == '\0')
+  if (cgetn_input(name, sizeof(name)) == 0)
     return;
-  name = strdup(input);
   cprintf("\r\nPreis in Cents:\r\n");
-  if ((input = get_input()) == NULL || *input == '\0' ||
-      (price = atoi(input)) == 0)
+  if ((price = cget_number(0)) <= 0)
     return;
   cprintf("\r\nWie oft schon verkauft? [0] \r\n");
-  if ((input = get_input()) == NULL)
+  if ((times_sold = cget_number(0)) < 0)
     return;
   memset(status.status[status.num_items].item_name, '\0',
          MAX_ITEM_NAME_LENGTH + 1);
   strncpy(status.status[status.num_items].item_name, name,
           MAX_ITEM_NAME_LENGTH);
   status.status[status.num_items].price = price;
-  status.status[status.num_items].times_sold = atoi(input);
+  status.status[status.num_items].times_sold = times_sold;
   status.num_items++;
-  free(name);
 }
 
 static void _delete_item(BYTE num) {
@@ -75,17 +74,19 @@ static void _delete_item(BYTE num) {
 }
 
 static void delete_item(void) {
-  char *input;
-  BYTE num, last;
-
+  int16_t num;
+  uint8_t last;
   cprintf("\r Welcher Eintrag soll geloescht werden?\r\n");
-  if ((input = get_input()) == NULL || *input == '\0')
+
+  num = cget_number(-1);
+  if (num < 0)
     return;
-  num = atoi(input);
+
   if (status.num_items > 1) {
     /* Swap last item with this one and delete the last one to avoid holes */
     last = (status.num_items - 1);
-    strcpy(status.status[num].item_name, status.status[last].item_name);
+    strncpy(status.status[num].item_name, status.status[last].item_name,
+            MAX_ITEM_NAME_LENGTH);
     status.status[num].price = status.status[last].price;
     status.status[num].times_sold = status.status[last].times_sold;
     _delete_item(last);
@@ -128,7 +129,7 @@ static void itemz_manager() {
       exit(0);
     default:
       cprintf("Unbekannter Befehl, druecke RETURN...\r\n");
-      get_input();
+      cget_return();
     }
   }
 }
index c7c2cc471adff599b6d9591bebc259220aa60b7c..d20ad93d0ee2039ccc1d8b1f7bd51df93c3092e0 100644 (file)
@@ -4,7 +4,6 @@
  * See LICENSE for license information
  *
  */
-#define _IS_KASSE
 #include <stdio.h>
 #include <conio.h>
 #include <stdlib.h>
 #include "print.h"
 #include "version.h"
 #include "vdc_patch_charset.h"
+#include "globals.h"
 // drucker 4 oder 5
 // graphic 4,0,10
 
 void print_item(BYTE i) {
-  char profit[10];
+  char profit[EUR_FORMAT_MINLEN];
   if (format_euro(profit, sizeof(profit), status.status[i].price) == NULL) {
     cprintf("Preis %ld konnte nicht umgerechnet werden\r\n",
             status.status[i].price);
@@ -42,9 +42,9 @@ void print_item(BYTE i) {
 static void print_screen(void) {
   BYTE i = 0;
   char *time = get_time();
-  char profit[10];
+  char profit[EUR_FORMAT_MINLEN];
   clrscr();
-  if (format_euro(profit, 10, money) == NULL) {
+  if (format_euro(profit, sizeof(profit), money) == NULL) {
     cprintf("Einnahme %ld konnte nicht umgerechnet werden\r\n", money);
     exit(1);
   }
@@ -112,177 +112,74 @@ static void print_screen(void) {
 static void print_log(char *name, int item_price, int einheiten, char *nickname,
                       char *rest) {
   char *time = get_time();
-  char price[10];
-  /* Format:
-     Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!)
-     -- 6-stellig
-     Uhrzeit -- 8-stellig
-     Eintragname (= Getränk) -- 9-stellig
-     Preis (in Cents) -- 9-stellig
-     Anzahl -- 2-stellig
-     Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig
-     restguthaben (9-stellig)
-
-     + 7 leerzeichen
-     --> 48 zeichen
-     */
-  if (format_euro(price, 10, item_price) == NULL) {
+  char price[EUR_FORMAT_MINLEN];
+  if (format_euro(price, sizeof(price), item_price) == NULL) {
     cprintf("Preis %d konnte nicht umgerechnet werden\r\n", item_price);
     exit(1);
   }
 
-  sprintf(print_buffer, "%c[%3u] %s - %-" xstr(
-                            MAX_ITEM_NAME_LENGTH) "s - %s - %s - %d - an %s\r",
+  /* TODO: teach the EUR sign to the printer.
+   * Until then, we just overwrite it with "E" */
+  price[EUR_FORMAT_MINLEN - 1] = 'E';
+  rest[EUR_FORMAT_MINLEN - 1] = 'E';
+
+  /* clang-format off */
+  sprintf(print_buffer,
+          /* enable lower case letters */
+          "%c"
+          /*  Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!)
+              -- 5-stellig */
+          "[%3u] "
+          /* Uhrzeit -- 8-stellig */
+          "%8s - "
+          /*  Eintragname (= Getränk) -- 9-stellig */
+          "%-" xstr(MAX_ITEM_NAME_LENGTH) "s - "
+          /*  Preis (in Cents) -- 7-stellig */
+          "%" xstr(sizeof(price) - 1) "s - "
+          /*  restguthaben (7-stellig) */
+          "%" xstr(sizeof(rest) - 1) "s - "
+          /*  Anzahl -- 2-stellig */
+          "%2d - "
+          /*  Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig */
+          "an %" xstr(NICKNAME_MAX_LEN)"s\r",
           17, status.transaction_id, time, name, price, rest, einheiten,
           (*nickname != '\0' ? nickname : "Unbekannt"));
+  /* clang-format on */
   status.transaction_id++;
   print_the_buffer();
 }
 
 /* dialog which is called for each bought item */
 static signed int buy(char *name, unsigned int price) {
-  int negative = 1;
-  char entered[5] = {'1', 0, 0, 0, 0};
-  BYTE i = 0, matches = 0;
-  BYTE c, x, y, nickname_len;
+  BYTE matches = 0;
+  BYTE c, nickname_len;
   int einheiten;
   char nickname[NICKNAME_MAX_LEN + 1];
-  char rest[11];
+  char rest[EUR_FORMAT_MINLEN];
   struct credits_t *credit;
 
-  memset(nickname, '\0', sizeof(nickname));
-  memset(rest, ' ', sizeof(rest));
-  rest[8] = '\0';
-
   clrscr();
   cprintf("Wieviel Einheiten \"%s\"? [1] \r\n", name);
-  x = wherex();
-  y = wherey();
-  while (1) {
-    /* Buffer-Ende erreicht? */
-    if (i == 4)
-      break;
 
-    c = cgetc();
-    /* Enter */
-    if (c == PETSCII_CR)
-      break;
-    /* Backspace */
-    if (c == PETSCII_DEL) {
-      if (i == 0)
-        continue;
-      entered[--i] = '\0';
-      cputcxy(x + i, y, ' ');
-      gotoxy(x + i, y);
-      continue;
-    }
-    if (c == 27) {
-      cprintf("Kauf abgebrochen, dr" uUML "cke RETURN...\r\n");
-      get_input();
-      return 1;
-    }
-    if (c == '-' && i == 0) {
-      negative = -1;
-      cputc(c);
-    } else if (c >= PETSCII_0 && c <= PETSCII_9) {
-      entered[i++] = c;
-      cputc(c);
-    }
-
-    /* Ungültige Eingabe (keine Ziffer), einfach ignorieren */
-  }
-  einheiten = atoi(entered) * negative;
+  einheiten = cget_number(1);
 
   if (einheiten > 100 || einheiten < -100 || einheiten == 0) {
     cprintf("\r\nEinheit nicht in [-100, 100] oder 0, Abbruch, dr" uUML "cke "
             "RETURN...\r\n");
-    cgetc();
+    cget_return();
     return 1;
   }
 
   cprintf("\r\nAuf ein Guthaben kaufen? Wenn ja, Nickname eingeben:\r\n");
-  {
-    BYTE i;
-    BYTE x;
-    BYTE y;
-    BYTE matches;
-    char *uniquematch;
-    input_terminator_t terminator;
-    while (1) {
-      terminator = get_input_terminated_by(INPUT_TERMINATOR_RETURN |
-                                               INPUT_TERMINATOR_SPACE,
-                                           nickname, sizeof(nickname));
-
-      /* Clear the screen from any previous completions */
-      x = wherex();
-      y = wherey();
-      for (i = 1; i < 7; i++) {
-        /* "Completion:" is longer than NICKNAME_MAX_LEN */
-        cclearxy(0, y + i, strlen("Completion:"));
-      }
-      gotoxy(x, y);
+  nickname_len = cget_nickname(nickname, sizeof(nickname));
 
-      if (terminator != INPUT_TERMINATOR_SPACE) {
-        break;
-      }
-
-      matches = 0;
-      uniquematch = NULL;
-      for (i = 0; i < credits.num_items; i++) {
-        if (strncmp(nickname, credits.credits[i].nickname, strlen(nickname)) !=
-            0) {
-          continue;
-        }
-        matches++;
-        if (matches > 1) {
-          break;
-        }
-        uniquematch = credits.credits[i].nickname;
-      }
-      if (matches == 1) {
-        /* Display the rest of the nickname */
-        textcolor(TC_LIGHT_GREEN);
-        cprintf("%s", uniquematch + strlen(nickname));
-        textcolor(TC_LIGHT_GRAY);
-        strcat(nickname, uniquematch + strlen(nickname));
-      } else {
-        /* Multiple nicknames match what was entered so far. Abort and
-         * display all matches, then prompt the user again. */
-        char completion[NICKNAME_MAX_LEN + 1];
-        BYTE len = strlen(nickname);
-        x = wherex();
-        y = wherey();
-        cprintf("\r\nCompletion:\r\n");
-        matches = 0;
-        for (i = 0; i < credits.num_items; i++) {
-          if (strncmp(nickname, credits.credits[i].nickname, len) != 0) {
-            continue;
-          }
-          if (++matches == 5) {
-            cprintf("...\r\n");
-            break;
-          }
-          strcpy(completion, credits.credits[i].nickname);
-          *(completion + len) = '\0';
-          cprintf("%s", completion);
-          textcolor(TC_LIGHT_GREEN);
-          cprintf("%c", *(credits.credits[i].nickname + len));
-          textcolor(TC_LIGHT_GRAY);
-          cprintf("%s\r\n", completion + len + 1);
-        }
-        gotoxy(x, y);
-      }
-    }
-  }
-
-  if (*nickname != '\0' && *nickname != 32) {
-    nickname_len = strlen(nickname);
+  if (nickname_len && *nickname != '\0' && *nickname != PETSCII_SP) {
     /* go through credits and remove the amount of money or set nickname
      * to NULL if no such credit could be found */
     credit = find_credit(nickname);
     if (credit != NULL) {
       while ((signed int)credit->credit < ((signed int)price * einheiten)) {
-        if (format_euro(rest, 10, credit->credit) == NULL) {
+        if (format_euro(rest, sizeof(rest), credit->credit) == NULL) {
           cprintf("Preis %d konnte nicht umgerechnet werden\r\n",
                   credit->credit);
           exit(1);
@@ -300,7 +197,7 @@ static signed int buy(char *name, unsigned int price) {
       /* substract money */
       credit->credit -= (price * einheiten);
 
-      if (format_euro(rest, 10, credit->credit) == NULL) {
+      if (format_euro(rest, sizeof(rest), credit->credit) == NULL) {
         cprintf("Preis %d konnte nicht umgerechnet werden\r\n", credit->credit);
         exit(1);
       }
@@ -310,20 +207,16 @@ static signed int buy(char *name, unsigned int price) {
               "cke RETURN...\r\n",
               nickname, rest);
       textcolor(TC_LIGHT_GRAY);
-      get_input();
+      cget_return();
       matches++;
     } else {
       textcolor(TC_LIGHT_RED);
       cprintf("\r\nNickname nicht gefunden in der Guthabenverwaltung! Abbruch, "
               "dr" uUML "cke RETURN...\r\n");
       textcolor(TC_LIGHT_GRAY);
-      get_input();
+      cget_return();
       return 0;
     }
-  } else {
-    /* Ensure that nickname is NULL if it's empty because it's used in print_log
-     */
-    *nickname = '\0';
   }
 
   money += price * einheiten;
@@ -337,7 +230,7 @@ static signed int buy(char *name, unsigned int price) {
 void buy_stock(BYTE n) {
   if (n >= status.num_items || status.status[n].item_name == NULL) {
     cprintf("FEHLER: Diese Einheit existiert nicht.\r\n");
-    get_input();
+    cget_return();
     return;
   }
 
@@ -346,38 +239,23 @@ void buy_stock(BYTE n) {
 }
 
 void buy_custom(void) {
-  BYTE c = 0, i = 0;
-  int negative = 1;
-  char entered[5] = {'1', 0, 0, 0, 0};
-  char *input, name[20];
+  char name[MAX_ITEM_NAME_LENGTH + 1];
   int price;
 
   clrscr();
-  memset(name, '\0', 20);
   cprintf("\r\nWas soll gekauft werden?\r\n");
-  input = get_input();
-  strncpy(name, input, 20);
-  if (*name == '\0')
+  if (cgetn_input(name, sizeof(name)) == 0)
     return;
 
   cprintf("\r\nWie teuer ist \"%s\" (in cents)?\r\n", name);
-  while (1) {
-    c = cgetc();
-    if (c == 13)
-      break;
-    cputc(c);
-    if (c == 27) {
-      cprintf("Kauf abgebrochen, dr" uUML "cke RETURN...\r\n");
-      get_input();
-      return;
-    } else if (c == '-' && i == 0)
-      negative = -1;
-    else if (c > 47 && c < 58)
-      entered[i++] = c;
-  }
-  price = atoi(entered) * negative;
 
-  cprintf("\r\n");
+  price = cget_number(0);
+
+  if (price == 0) {
+    cprintf("Kauf abgebrochen, dr" uUML "cke RETURN...\r\n");
+    cget_return();
+    return;
+  }
 
   buy(name, price);
 }
@@ -407,6 +285,8 @@ int main(void) {
   char *c;
   char *time;
 
+  init_globals();
+
   videomode(VIDEOMODE_80x25);
 
   /* clock CPU at double the speed (a whopping 2 Mhz!) */
@@ -458,7 +338,7 @@ int main(void) {
     print_screen();
     c = get_input();
     /* ...display dialogs eventually */
-    if (*c > 47 && *c < 58) {
+    if (*c >= PETSCII_0 && *c <= PETSCII_9) {
       /* if the input starts with a digit, we will interpret it as a number
        * for the item to be sold */
       buy_stock(atoi(c));
@@ -473,7 +353,7 @@ int main(void) {
       log_flush();
       cprintf("ok\r\nStatefile/Creditfile/Log gesichert, dr" uUML
               "cke RETURN...\r\n");
-      get_input();
+      cget_return();
     } else if (*c == 'g') {
       credit_manager();
     } else if (*c == 'z') {
index 665f99feee090b7d19f34b0dca49eef3f084c92e..a0e63df655aed53ab9b2d2be68a6ec2fcefb0108 100644 (file)
@@ -10,8 +10,9 @@
 #include <cbm.h>
 
 #include "general.h"
-#define _IS_PRINT
+#define IS_PRINT_C
 #include "print.h"
+#include "globals.h"
 
 /* NOTE: undocumented function which scratches files
    We need to use this function because linking unistd.h
@@ -36,19 +37,34 @@ void init_log(void) {
 }
 
 void print_the_buffer(void) {
-  BYTE c;
+  BYTE status;
+  char *c;
+
+  if (!printing)
+    return;
+
 RETRY:
-  c = cbm_open((BYTE)4, (BYTE)4, (BYTE)0, NULL);
-  if (c != 0) {
-    c128_perror(c, "cbm_open(printer)");
-    if (retry_or_quit() == 'q')
+  status = cbm_open((BYTE)4, (BYTE)4, (BYTE)0, NULL);
+  if (status != 0) {
+    c128_perror(status, "cbm_open(printer)");
+
+    do {
+      cprintf("\r\nr)etry, c)ontinue or q)uit?\r\n");
+      c = get_input();
+    } while ((*c != 'r') && (*c != 'c') && (*c != 'q'));
+
+    if (*c == 'q')
       exit(1);
+    else if (*c == 'c') {
+      printing = 0;
+      return;
+    }
 
     goto RETRY;
   }
-  c = cbm_write((BYTE)4, print_buffer, strlen(print_buffer));
-  if (c != strlen(print_buffer)) {
-    c128_perror(c, "write(printer)");
+  status = cbm_write((BYTE)4, print_buffer, strlen(print_buffer));
+  if (status != strlen(print_buffer)) {
+    c128_perror(status, "write(printer)");
     if (retry_or_quit() == 'q')
       exit(1);
     goto RETRY;
index 9632181e3c5ac8d287a23d3121c709d339b1cf20..b4501a0110e8b9fb492fe2f31adc9c04c9d2f635 100644 (file)
@@ -8,7 +8,10 @@
 #include "kasse.h"
 #include "credit_manager.h"
 
+#warning "please fix me, load_state() isn't available anymore"
 int main() {
+  /* clang-format off */
+/*
   BYTE i = 0;
   char euro[10];
   load_items();
@@ -32,4 +35,6 @@ int main() {
   cprintf("strlen(%s)==%d\n", status.status[1].item_name,
           strlen(status.status[1].item_name));
   cprintf("%d %d %d\n", status.status[1].item_name[0], '\r', '\n');
+*/
+  return -1;
 }