--- /dev/null
+-I/usr/share/cc65/include
+-Iinclude
+-nostdlibinc
+-nobuiltininc
+-D__fastcall__=''
--- /dev/null
+((nil . ())
+ (c-mode . ((c-basic-offset . 2)
+ (indent-tabs-mode . nil)
+ (flycheck-clang-include-path . ("/usr/share/cc65/include"))
+ (flycheck-clang-language-standard . "c99"))))
build/
*.P00
itemz
-*.d64
+*.d71
include/version.h
include/charset_umlauts.h
tags
charmap
ascii
*.lbl
+TAGS
+test/test
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}\"" > $@
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
${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]
-#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
#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
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
void save_items(void);
void save_credits(void);
-#endif /*CONFIG_H_*/
+#endif /* CONFIG_H */
-#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 */
-#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 {
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 *);
#define PETSCII_CR 13
/* Delete */
#define PETSCII_DEL 20
+/* Escape */
+#define PETSCII_ESC 27
/* Space */
#define PETSCII_SP 32
#define PETSCII_0 48
#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) */
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) > (b) ? (b) : (a))
-#endif /*GENERAL_H_*/
+#endif /* GENERAL_H */
--- /dev/null
+#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 */
-#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
-#ifndef _PRINT_H
-#define _PRINT_H
+#ifndef PRINT_H
+#define PRINT_H
void init_log(void);
void print_the_buffer(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
-#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);
#define uUML "\xA9"
#define szLIG "\xBF"
-#endif // __VDC_PATCH_CHARSET_H_
+#endif /* VDC_PATCH_CHARSET_H */
-#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);
unsigned n);
extern void __fastcall__ vdc_load_thinfont(void);
-#endif // __VDC_UTIL_H_
+#endif /* VDC_UTIL_H */
* See LICENSE for license information
*
*/
-#define _IS_CONFIG_C
+#define IS_CONFIG_C
#include <stdlib.h>
#include <conio.h>
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");
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);
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;
}
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;
}
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 {
}
void credit_manager() {
+ char nickname[NICKNAME_MAX_LEN + 1];
char *c;
while (1) {
credit_print_screen();
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':
return;
default:
cprintf("Unbekannter Befehl, dr" uUML "cke RETURN...\r\n");
- get_input();
+ cget_return();
}
}
}
#include <stdio.h>
#include <string.h>
#include <conio.h>
+#include <stdint.h>
#include "general.h"
+#include "config.h"
#include "vdc_patch_charset.h"
/*
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 {
}
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;
}
--- /dev/null
+#define IS_GLOBALS_C
+#include "globals.h"
+
+void init_globals(void) {
+ printing = 1;
+ return;
+}
#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) {
}
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);
exit(0);
default:
cprintf("Unbekannter Befehl, druecke RETURN...\r\n");
- get_input();
+ cget_return();
}
}
}
* 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);
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);
}
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);
/* 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);
}
"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;
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;
}
}
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);
}
char *c;
char *time;
+ init_globals();
+
videomode(VIDEOMODE_80x25);
/* clock CPU at double the speed (a whopping 2 Mhz!) */
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));
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') {
#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
}
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;
#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();
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;
}