2 * RGB2R-C128-Kassenprogramm
3 * © 2007-2009 phil_fry, sECuRE, sur5r
4 * See LICENSE for license information
18 #include "credit_manager.h"
25 void print_item(BYTE i) {
27 if (format_euro(profit, sizeof(profit), status.status[i].price) == NULL) {
28 cprintf("Preis %ld konnte nicht umgerechnet werden\r\n",
29 status.status[i].price);
34 textcolor(TC_LIGHT_GRAY);
35 cprintf(": %-" xstr(MAX_ITEM_NAME_LENGTH) "s \xDD%s, %3dx ",
36 status.status[i].item_name, profit, status.status[i].times_sold);
39 /* Hauptbildschirm ausgeben */
40 static void print_screen(void) {
42 char *time = get_time();
45 if (format_euro(profit, 10, money) == NULL) {
46 cprintf("Einnahme %ld konnte nicht umgerechnet werden\r\n", money);
50 cprintf("C128-Kassenprogramm (phil_fry, sECuRE, sur5r) " GV "\r\n");
51 textcolor(TC_LIGHT_GRAY);
52 cprintf("\r\nUhrzeit: %s (wird nicht aktualisiert)\r\n"
53 "Eingenommen: %s, Verkauft: %ld Dinge, Drucken: %s\r\n",
54 time, profit, items_sold, (printing == 1 ? "ein" : "aus"));
55 textcolor(TC_LIGHT_GRAY);
57 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB2"
58 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB2"
59 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB2"
60 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xAE"
62 for (; i < min(status.num_items, 15); ++i) {
68 /* if we have more than 15 items, use the second column */
69 if ((i + 15) < status.num_items) {
73 cprintf(" \xDD \xDD");
79 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB1"
80 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB1"
81 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB1"
82 "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xBD"
86 textcolor(TC_LIGHT_GRAY);
87 cprintf(") Daten sichern ");
90 textcolor(TC_LIGHT_GRAY);
91 cprintf(") Guthabenverwaltung\r\n");
94 textcolor(TC_LIGHT_GRAY);
95 cprintf(") Zeit setzen ");
98 textcolor(TC_LIGHT_GRAY);
99 cprintf(") Freitext verkaufen ");
100 textcolor(TC_YELLOW);
102 textcolor(TC_LIGHT_GRAY);
103 cprintf(") Beenden\r\n");
107 * Prints a line and logs it to file. Every line can be at max 80 characters.
110 static void print_log(char *name, int item_price, int einheiten, char *nickname,
112 char *time = get_time();
115 Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!)
118 Eintragname (= Getränk) -- 9-stellig
119 Preis (in Cents) -- 9-stellig
121 Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig
122 restguthaben (9-stellig)
127 if (format_euro(price, 10, item_price) == NULL) {
128 cprintf("Preis %d konnte nicht umgerechnet werden\r\n", item_price);
132 sprintf(print_buffer, "%c[%3u] %s - %-" xstr(
133 MAX_ITEM_NAME_LENGTH) "s - %s - %s - %d - an %s\r",
134 17, status.transaction_id, time, name, price, rest, einheiten,
135 (*nickname != '\0' ? nickname : "Unbekannt"));
136 status.transaction_id++;
140 /* dialog which is called for each bought item */
141 static signed int buy(char *name, unsigned int price) {
143 char entered[5] = {'1', 0, 0, 0, 0};
144 BYTE i = 0, matches = 0;
145 BYTE c, x, y, nickname_len;
147 char nickname[NICKNAME_MAX_LEN + 1];
149 struct credits_t *credit;
151 memset(nickname, '\0', sizeof(nickname));
152 memset(rest, ' ', sizeof(rest));
156 cprintf("Wieviel Einheiten \"%s\"? [1] \r\n", name);
160 /* Buffer-Ende erreicht? */
169 if (c == PETSCII_DEL) {
173 cputcxy(x + i, y, ' ');
178 cprintf("Kauf abgebrochen, druecke RETURN...\r\n");
182 if (c == '-' && i == 0) {
185 } else if (c >= PETSCII_0 && c <= PETSCII_9) {
190 /* Ungültige Eingabe (keine Ziffer), einfach ignorieren */
192 einheiten = atoi(entered) * negative;
194 if (einheiten > 100 || einheiten < -100 || einheiten == 0) {
195 cprintf("\r\nEinheit nicht in [-100, 100] oder 0, Abbruch, druecke "
201 cprintf("\r\nAuf ein Guthaben kaufen? Wenn ja, Nickname eingeben:\r\n");
208 input_terminator_t terminator;
210 terminator = get_input_terminated_by(INPUT_TERMINATOR_RETURN |
211 INPUT_TERMINATOR_SPACE,
212 nickname, sizeof(nickname));
214 /* Clear the screen from any previous completions */
217 for (i = 1; i < 7; i++) {
218 /* "Completion:" is longer than NICKNAME_MAX_LEN */
219 cclearxy(0, y + i, strlen("Completion:"));
223 if (terminator != INPUT_TERMINATOR_SPACE) {
229 for (i = 0; i < credits.num_items; i++) {
230 if (strncmp(nickname, credits.credits[i].nickname, strlen(nickname)) !=
238 uniquematch = credits.credits[i].nickname;
241 /* Display the rest of the nickname */
242 textcolor(TC_LIGHT_GREEN);
243 cprintf("%s", uniquematch + strlen(nickname));
244 textcolor(TC_LIGHT_GRAY);
245 strcat(nickname, uniquematch + strlen(nickname));
247 /* Multiple nicknames match what was entered so far. Abort and
248 * display all matches, then prompt the user again. */
249 char completion[NICKNAME_MAX_LEN + 1];
250 BYTE len = strlen(nickname);
253 cprintf("\r\nCompletion:\r\n");
255 for (i = 0; i < credits.num_items; i++) {
256 if (strncmp(nickname, credits.credits[i].nickname, len) != 0) {
259 if (++matches == 5) {
263 strcpy(completion, credits.credits[i].nickname);
264 *(completion + len) = '\0';
265 cprintf("%s", completion);
266 textcolor(TC_LIGHT_GREEN);
267 cprintf("%c", *(credits.credits[i].nickname + len));
268 textcolor(TC_LIGHT_GRAY);
269 cprintf("%s\r\n", completion + len + 1);
276 if (*nickname != '\0' && *nickname != 32) {
277 nickname_len = strlen(nickname);
278 /* go through credits and remove the amount of money or set nickname
279 * to NULL if no such credit could be found */
280 credit = find_credit(nickname);
281 if (credit != NULL) {
282 while ((signed int)credit->credit < ((signed int)price * einheiten)) {
283 if (format_euro(rest, 10, credit->credit) == NULL) {
284 cprintf("Preis %d konnte nicht umgerechnet werden\r\n",
289 "\r\n%s hat nicht genug Geld (%s). e) einzahlen a) abbruch \r\n",
293 deposit_credit(nickname);
298 /* substract money */
299 credit->credit -= (price * einheiten);
301 if (format_euro(rest, 10, credit->credit) == NULL) {
302 cprintf("Preis %d konnte nicht umgerechnet werden\r\n", credit->credit);
306 textcolor(TC_LIGHT_GREEN);
307 cprintf("\r\nVerbleibendes Guthaben fuer %s: %s. Druecke RETURN...\r\n",
309 textcolor(TC_LIGHT_GRAY);
313 textcolor(TC_LIGHT_RED);
314 cprintf("\r\nNickname nicht gefunden in der Guthabenverwaltung! Abbruch, "
315 "druecke RETURN...\r\n");
316 textcolor(TC_LIGHT_GRAY);
321 /* Ensure that nickname is NULL if it's empty because it's used in print_log
326 money += price * einheiten;
327 items_sold += einheiten;
329 print_log(name, price, einheiten, nickname, rest);
334 void buy_stock(BYTE n) {
335 if (n >= status.num_items || status.status[n].item_name == NULL) {
336 cprintf("FEHLER: Diese Einheit existiert nicht.\r\n");
341 status.status[n].times_sold +=
342 buy(status.status[n].item_name, status.status[n].price);
345 void buy_custom(void) {
348 char entered[5] = {'1', 0, 0, 0, 0};
349 char *input, name[20];
353 memset(name, '\0', 20);
354 cprintf("\r\nWas soll gekauft werden?\r\n");
356 strncpy(name, input, 20);
360 cprintf("\r\nWie teuer ist \"%s\" (in cents)?\r\n", name);
367 cprintf("Kauf abgebrochen, druecke RETURN...\r\n");
370 } else if (c == '-' && i == 0)
372 else if (c > 47 && c < 58)
375 price = atoi(entered) * negative;
382 void set_time_interactive(void) {
383 BYTE part[3] = {'0', '0', '\0'};
385 char *time_input, *time;
386 cprintf("Gib die aktuelle Uhrzeit ein (Format HHMMSS):\r\n");
387 time_input = get_input();
388 part[0] = time_input[0];
389 part[1] = time_input[1];
391 part[0] = time_input[2];
392 part[1] = time_input[3];
394 part[0] = time_input[4];
395 part[1] = time_input[5];
397 set_time(tp1, tp2, tp3);
400 cprintf("\r\nZeit gesetzt: %s\r\n", time);
407 videomode(VIDEOMODE_80x25);
409 /* clock CPU at double the speed (a whopping 2 Mhz!) */
414 /* Allocate logging buffer memory */
417 /* Set time initially, c128 doesn't know it */
418 set_time_interactive();
420 /* disable interrupt driven VIC screen editor */
423 /* Load configuration */
426 /* Load items (= drinks) */
432 sprintf(print_buffer, "%c----------------------------------------------------"
433 "----------------------------\r",
436 sprintf(print_buffer, "%cC128-Kasse Version " GV "\r", 17);
439 sprintf(print_buffer,
440 "%cKasse gestartet um %s. Nutze logfile log-%u, offset %d.\r", 17,
441 time, log_num, log_heap_offset);
449 /* ...display dialogs eventually */
450 if (*c > 47 && *c < 58) {
451 /* if the input starts with a digit, we will interpret it as a number
452 * for the item to be sold */
454 } else if (*c == 'f') {
456 } else if (*c == 's') {
460 cprintf("\r\nStatefile/Creditfile/Log gesichert, druecke RETURN...\r\n");
462 } else if (*c == 'g') {
464 } else if (*c == 'z') {
465 set_time_interactive();
466 } else if (*c == 'q')
470 cprintf("\r\nBYEBYE\r\n");