2 * RGB2R-C128-Kassenprogramm
3 * (c) 2007-2008 phil_fry, sECuRE, sur5r
4 * See LICENSE for license information
17 #include "credit_manager.h"
22 /* NOTE: undocumented function which scratches files
23 We need to use this function because linking unistd.h
24 makes our program break at runtime.
26 unsigned char __fastcall__ _sysremove(const char *name);
28 static void sane_exit() {
34 /* Hauptbildschirm ausgeben */
35 static void print_screen() {
37 char *time = get_time();
40 if (format_euro(profit, 10, money) == NULL) {
41 cprintf("Einnahme %ld konnte nicht umgerechnet werden\r\n", money);
44 cprintf("C128-Kassenprogramm (phil_fry, sECuRE, sur5r)\r\
45 \r\nUhrzeit: %s (wird nicht aktualisiert)\r\
46 Eingenommen: %s, Verkauft: %ld Flaschen, Drucken: %s\r\n\r\n",
47 time, profit, items_sold, (printing == 1 ? "ein" : "aus"));
48 for (; i < status.num_items; ++i)
49 cprintf("Eintrag %x: %s (%d Cents, %d mal verkauft)\r\n",
50 i, status.status[i].item_name, status.status[i].price, status.status[i].times_sold);
51 cprintf("\r\nBefehle: s) Daten sichern d) Drucken umschalten\r\
52 g) Guthabenverwaltung z) Zeit setzen\r\
53 f) Freitext verkaufen q) Beenden\r\n");
56 static void log_file(const char *s) {
57 /* A log-entry has usually 50 bytes, so we take 64 bytes.
58 Because files are wrapped (log.0, log.1, ...) every 100
59 lines, we don't need more than 100 * 64 bytes. */
60 char *buffer = malloc(sizeof(char) * 64 * 100);
65 cprintf("No memory available\n");
68 if (((++log_lines_written) % 100) == 0)
70 sprintf(filename, "log-%d", log_num);
71 /* Don't read log if there were no lines written before */
72 if (log_lines_written != 1) {
73 if ((c = cbm_open((BYTE)8, (BYTE)8, (BYTE)0, filename)) != 0) {
74 c128_perror(c, "cbm_open(log)");
77 read = cbm_read((BYTE)8, buffer, sizeof(char) * 64 * 100);
81 if ((c = cbm_open((BYTE)8, (BYTE)8, (BYTE)1, filename)) != 0) {
82 c128_perror(c, "cbm_open(log)");
86 cprintf("Could not read existing logfile (read returned %d)\n", read);
89 strcpy(buffer+read, s);
90 c = cbm_write((BYTE)8, buffer, read+strlen(s));
91 if (c != (read+strlen(s))) {
92 cprintf("Could not save logfile (wrote %d bytes, wanted %d bytes), please make sure the floppy is not full!\n", c, (read+strlen(s)));
99 static char retry_or_quit() {
102 cprintf("\r\nr)etry or q)uit?\r\n");
104 } while ((*c != 'r') && (*c != 'q'));
108 /* Prints a line and logs it to file */
109 static void print_log(char *name, int item_price, int einheiten, char *nickname, char *rest) {
110 char *time = get_time();
113 Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!) -- 6-stellig
115 Eintragname (= Getränk) -- 9-stellig
116 Preis (in Cents) -- 7-stellig
118 Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig
119 restguthaben (9-stellig)
124 if (format_euro(price, 10, item_price) == NULL) {
125 cprintf("Preis %d konnte nicht umgerechnet werden\r\n", item_price);
129 sprintf(print_buffer, "%c[%lu] %s - %-9s - %s - r %s - %d - an %s\r", 17,
130 items_sold, time, name, price, rest,
131 einheiten, (*nickname != '\0' ? nickname : "Unbekannt"));
135 void print_the_buffer() {
138 c = cbm_open((BYTE)4, (BYTE)4, (BYTE)0, NULL);
140 c128_perror(c, "cbm_open(printer)");
141 if (retry_or_quit() == 'q')
146 c = cbm_write((BYTE)4, print_buffer, strlen(print_buffer));
147 if (c != strlen(print_buffer)) {
148 c128_perror(c, "write(printer)");
149 if (retry_or_quit() == 'q') {
157 log_file(print_buffer);
160 /* dialog which is called for each bought item */
161 BYTE buy(char *name, unsigned int price) {
163 char entered[5] = {'1', 0, 0, 0, 0};
164 BYTE i = 0, matches = 0;
165 BYTE c, nickname_len;
170 struct credits_t *credit;
172 memset(rest, ' ', sizeof(rest));
175 cprintf("Wieviel Einheiten \"%s\"? [1] \r\n", name);
181 cprintf("Kauf abgebrochen, druecke RETURN...\r\n");
184 } else if (c == '-' && i == 0)
186 else if (c > 47 && c < 58)
189 einheiten = atoi(entered) * negative;
192 cprintf("%dx %s fuer ", einheiten, name);
195 cprintf("\r\nAuf ein Guthaben kaufen? Wenn ja, Nickname eingeben:\r\n");
197 strncpy(nickname, input, 11);
198 if (*nickname != '\0') {
200 cprintf("%s\r\n", nickname);
204 if (nickname != NULL && *nickname != '\0' && *nickname != 32) {
205 nickname_len = strlen(nickname);
206 /* go through credits and remove the amount of money or set nickname
207 * to NULL if no such credit could be found */
208 credit = find_credit(nickname);
209 if (credit != NULL) {
210 if ((signed int)credit->credit < ((signed int)price * einheiten)) {
211 cprintf("Sorry, %s hat nicht genug Geld :-(\r\n", nickname);
215 /* substract money */
216 credit->credit -= (price * einheiten);
218 if (format_euro(rest, 10, credit->credit) == NULL) {
219 cprintf("Preis %d konnte nicht umgerechnet werden\r\n", credit->credit);
223 cprintf("\r\nVerbleibendes Guthaben fuer %s: %s. Druecke RETURN...\r\n",
226 cprintf("\r\nDein verbleibendes Guthaben betraegt %s.\r\n", rest);
231 cprintf("\r\nNickname nicht gefunden in der Guthabenverwaltung! Abbruch, druecke RETURN...\r\n");
236 /* Ensure that nickname is NULL if it's empty because it's used in print_log */
240 money += price * einheiten;
241 items_sold += einheiten;
243 print_log(name, price, einheiten, nickname, rest);
248 void buy_stock(BYTE n) {
249 if (n >= status.num_items || status.status[n].item_name == NULL) {
250 cprintf("FEHLER: Diese Einheit existiert nicht.\r\n");
255 status.status[n].times_sold += buy(status.status[n].item_name, status.status[n].price);
261 char entered[5] = {'1', 0, 0, 0, 0};
262 char *input, name[20];
266 memset(name, '\0', 20);
267 cprintf("\r\nWas soll gekauft werden?\r\n");
269 strncpy(name, input, 20);
273 cprintf("\r\nWie teuer ist \"%s\" (in cents)?\r\n", name);
279 cprintf("Kauf abgebrochen, druecke RETURN...\r\n");
282 } else if (c == '-' && i == 0)
284 else if (c > 47 && c < 58)
287 price = atoi(entered) * negative;
294 void set_time_interactive() {
295 BYTE part[3] = {'0', '0', '\0'};
297 char *time_input, *time;
298 cprintf("Gib die aktuelle Uhrzeit ein (Format HHMMSS):\r\n");
299 time_input = get_input();
300 part[0] = time_input[0];
301 part[1] = time_input[1];
303 part[0] = time_input[2];
304 part[1] = time_input[3];
306 part[0] = time_input[4];
307 part[1] = time_input[5];
309 set_time(tp1, tp2, tp3);
312 cprintf("\r\nZeit gesetzt: %s\r\n", time);
320 /* Set time initially, c128 doesn't know it */
321 set_time_interactive();
325 /* Load configuration */
327 cprintf("got %d logfiles\r\n", log_num);
329 /* Load items (= drinks) */
336 /* ...display dialogs eventually */
337 if (*c > 47 && *c < 58) {
338 buy_stock((*c) - 48);
342 } else if (*c == 'f') {
347 } else if (*c == 's') {
350 cprintf("Statefile/Creditfile gesichert, druecke RETURN...\r\n");
352 } else if (*c == 'd') {
353 /* enable/disable printing */
354 printing = (printing == 1 ? 0 : 1);
355 cprintf("Drucken ist nun %s, druecke RETURN...\r\n",
356 (printing == 1 ? "eingeschaltet" : "ausgeschaltet"));
358 } else if (*c == 'g') {
360 } else if (*c == 'z') {
361 set_time_interactive();
362 } else if (*c == 'q')
365 cprintf("BYEBYE\r\n");