+/* 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;
+ int einheiten;
+ char nickname[NICKNAME_MAX_LEN + 1];
+ char rest[11];
+ 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, druecke 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;
+
+ if (einheiten > 100 || einheiten < -100 || einheiten == 0) {
+ cprintf("\r\nEinheit nicht in [-100, 100] oder 0, Abbruch, druecke "
+ "RETURN...\r\n");
+ cgetc();
+ 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);
+
+ 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);
+ /* 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) {
+ cprintf("Preis %d konnte nicht umgerechnet werden\r\n",
+ credit->credit);
+ exit(1);
+ }
+ cprintf(
+ "\r\n%s hat nicht genug Geld (%s). e) einzahlen a) abbruch \r\n",
+ nickname, rest);
+ c = cgetc();
+ if (c == 'e') {
+ deposit_credit(nickname);
+ } else {
+ return 0;
+ }
+ }
+ /* substract money */
+ credit->credit -= (price * einheiten);
+
+ if (format_euro(rest, 10, credit->credit) == NULL) {
+ cprintf("Preis %d konnte nicht umgerechnet werden\r\n", credit->credit);
+ exit(1);
+ }
+
+ textcolor(TC_LIGHT_GREEN);
+ cprintf("\r\nVerbleibendes Guthaben fuer %s: %s. Druecke RETURN...\r\n",
+ nickname, rest);
+ textcolor(TC_LIGHT_GRAY);
+ get_input();
+ matches++;
+ } else {
+ textcolor(TC_LIGHT_RED);
+ cprintf("\r\nNickname nicht gefunden in der Guthabenverwaltung! Abbruch, "
+ "druecke RETURN...\r\n");
+ textcolor(TC_LIGHT_GRAY);
+ get_input();
+ return 0;
+ }
+ } else {
+ /* Ensure that nickname is NULL if it's empty because it's used in print_log
+ */
+ *nickname = '\0';
+ }
+
+ money += price * einheiten;
+ items_sold += einheiten;
+ if (printing == 1)
+ print_log(name, price, einheiten, nickname, rest);
+
+ return einheiten;