void send_bid_history(void) { int r, buf_len = 0, widths[game.num_players]; player_t p; char buf[4096]; char buf2[512]; if (!game.bid_history) return; for (p = 0; p < game.num_players; p++) { widths[p] = strlen(get_player_name(p)); /* TODO if (widths[p] < game.max_bid_length) widths[p] = game.max_bid_length; */ buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "%*s%s", widths[p], get_player_name(p), p == game.num_players - 1 ? "" : " "); } buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "\n"); for (r = 0; r <= game.bid_rounds; r++) { for (p = 0; p < game.num_players; p++) { game.data->get_bid_text(buf2, sizeof(buf2), game.players[p].allbids[r]); buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "%*s%s", widths[p], buf2, p == game.num_players - 1 ? "" : " "); } buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "\n"); } set_global_message("Bid History", "%s", buf); }
void set_player_message(player_t p) { if (game.data == NULL) { /* silently fail; it's easier to check here than elsewhere */ return; } ggz_debug(DBG_MISC, "Setting player %d/%s's message.", p, get_player_name(p)); if (p < 0 || p >= game.num_players) ggz_error_msg("set_player_message(%d) called.", p); game.data->set_player_message(p); broadcast_player_message(game.players[p].seat); }
static void bridge_set_score_message(void) { player_t team; int widths[2], len = 0, i, g; char buf[4096] = ""; #define HORIZONTAL_LINE for (i=0; i<widths[0]+widths[1]+3; i++) \ len += snprintf(buf+len, sizeof(buf)-len, "%c", '-'); \ len += snprintf(buf+len, sizeof(buf)-len, "\n") #define BLANK_LINE len += snprintf(buf+len, sizeof(buf)-len, "%*s | %*s\n", widths[0], "", widths[1], "") len = snprintf(buf, sizeof(buf), "%s/%s | %s/%s\n", get_player_name(0), get_player_name(2), get_player_name(1), get_player_name(3)); for (team = 0; team < 2; team++) widths[team] = strlen(get_player_name(team)) + strlen(get_player_name(team + 2)) + 1; HORIZONTAL_LINE; BLANK_LINE; len += snprintf(buf + len, sizeof(buf) - len, "%*d | %-*d\n", widths[0], BRIDGE.points_above_line[0], widths[1], BRIDGE.points_above_line[1]); BLANK_LINE; for (g = 0; g <= BRIDGE.game_count; g++) { HORIZONTAL_LINE; len += snprintf(buf + len, sizeof(buf) - len, "%*d | %-*d\n", widths[0], BRIDGE.points_below_line[g][0], widths[1], BRIDGE.points_below_line[g][1]); } set_global_message("Scores", "%s", buf); }
int main(int argc, char **argv) { bool quiet = false; struct hwstub_device_t *hwdev; enum image_type_t type = IT_DETECT; // parse command line while(1) { static struct option long_options[] = { {"help", no_argument, 0, '?'}, {"quiet", no_argument, 0, 'q'}, {"type", required_argument, 0, 't'}, {0, 0, 0, 0} }; int c = getopt_long(argc, argv, "?qt:", long_options, NULL); if(c == -1) break; switch(c) { case -1: break; case 'q': quiet = true; break; case '?': usage(); break; case 't': if(strcmp(optarg, "raw") == 0) type = IT_RAW; else if(strcmp(optarg, "rockbox") == 0) type = IT_ROCKBOX; else if(strcmp(optarg, "detect") == 0) type = IT_DETECT; else { fprintf(stderr, "Unknown file type '%s'\n", optarg); return 1; } break; default: abort(); } } if(optind + 2 != argc) usage(); char *end; unsigned long addr = strtoul(argv[optind], &end, 0); if(*end) { fprintf(stderr, "Invalid load address\n"); return 2; } FILE *f = fopen(argv[optind + 1], "rb"); if(f == NULL) { fprintf(stderr, "Cannot open file for reading: %m\n"); return 3; } fseek(f, 0, SEEK_END); size_t size = ftell(f); fseek(f, 0, SEEK_SET); unsigned char *buffer = (unsigned char*)malloc(size); fread(buffer, size, 1, f); fclose(f); if(type == IT_ROCKBOX || type == IT_DETECT) { enum image_type_t det = detect_type(buffer, size); if(type == IT_ROCKBOX && det != IT_ROCKBOX) { if(!could_be_rockbox(buffer, size)) fprintf(stderr, "This file does not appear to be valid rockbox image.\n"); return 4; } if(type == IT_DETECT && det == IT_RAW) could_be_rockbox(buffer, size); type = det; if(type == IT_ROCKBOX) { if(!quiet) printf("Rockox image is for player %s (%.4s)\n", get_player_name(buffer + 4), buffer + 4); memmove(buffer, buffer + 8, size - 8); size -= 8; } } if(!quiet) { if(type == IT_RAW) printf("Loading raw image at %#lx\n", addr); else printf("Loading rockbox image at %#lx\n", addr); } // create usb context libusb_context *ctx; libusb_init(&ctx); libusb_set_debug(ctx, 3); // look for device if(!quiet) printf("Looking for device %#04x:%#04x...\n", HWSTUB_USB_VID, HWSTUB_USB_PID); libusb_device_handle *handle = libusb_open_device_with_vid_pid(ctx, HWSTUB_USB_VID, HWSTUB_USB_PID); if(handle == NULL) { fprintf(stderr, "No device found\n"); return 1; } // admin stuff libusb_device *mydev = libusb_get_device(handle); if(!quiet) { printf("device found at %d:%d\n", libusb_get_bus_number(mydev), libusb_get_device_address(mydev)); } hwdev = hwstub_open(handle); if(hwdev == NULL) { fprintf(stderr, "Cannot probe device!\n"); return 1; } // get hwstub information struct hwstub_version_desc_t hwdev_ver; int ret = hwstub_get_desc(hwdev, HWSTUB_DT_VERSION, &hwdev_ver, sizeof(hwdev_ver)); if(ret != sizeof(hwdev_ver)) { fprintf(stderr, "Cannot get version!\n"); goto Lerr; } if(hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || hwdev_ver.bMinor < HWSTUB_VERSION_MINOR) { printf("Warning: this tool is possibly incompatible with your device:\n"); printf("Device version: %d.%d.%d\n", hwdev_ver.bMajor, hwdev_ver.bMinor, hwdev_ver.bRevision); printf("Host version: %d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR); } ret = hwstub_rw_mem(hwdev, 0, addr, buffer, size); if(ret != (int)size) { fprintf(stderr, "Image write failed: %d\n", ret); goto Lerr; } hwstub_jump(hwdev, addr); hwstub_release(hwdev); return 0; Lerr: // display log if handled fprintf(stderr, "Device log:\n"); do { char buffer[128]; int length = hwstub_get_log(hwdev, buffer, sizeof(buffer) - 1); if(length <= 0) break; buffer[length] = 0; fprintf(stderr, "%s", buffer); }while(1); hwstub_release(hwdev); return 1; }
static void bridge_end_hand(void) { int points_above = 0, points_below = 0, tricks, g; int winning_team, team; int tricks_above, tricks_below; int vulnerable = BRIDGE.vulnerable[BRIDGE.declarer % 2]; char buf[512]; char buf2[512] = ""; char *bonus_text = BRIDGE.bonus == 1 ? "" : BRIDGE.bonus == 2 ? ", doubled" : ", redoubled"; /* calculate tricks over book */ tricks = game.players[BRIDGE.declarer].tricks + game.players[BRIDGE.dummy].tricks - 6; ggz_debug(DBG_GAME, "Contract was %d. Declarer made %d.", BRIDGE.contract, tricks); winning_team = (tricks >= BRIDGE.contract) ? BRIDGE.declarer % 2 : (BRIDGE.declarer + 1) % 2; snprintf(buf2, sizeof(buf2), "%s and %s get:\n", get_player_name(winning_team), get_player_name(winning_team + 2)); if (tricks >= BRIDGE.contract) { tricks_below = BRIDGE.contract; tricks_above = tricks - BRIDGE.contract; switch (BRIDGE.contract_suit) { case CLUBS: case DIAMONDS: points_below = 20 * tricks_below; points_above = 20 * tricks_above; break; case HEARTS: case SPADES: points_below = 30 * tricks_below; points_above = 30 * tricks_above; break; case BRIDGE_NOTRUMP: default: points_below = 30 * tricks_below + (tricks_below > 0) ? 10 : 0; points_above = 30 * tricks_above; break; } points_below *= BRIDGE.bonus; points_above *= BRIDGE.bonus; snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), " %d points below the line for %d %s%s.", points_below, BRIDGE.contract, long_bridge_suit_names[BRIDGE.contract_suit], bonus_text); if (points_above) snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), " %d points above the line for %d overtricks%s.", points_above, tricks_above, bonus_text); /* you get a bonus just for making a doubled/redoubled contract */ if (BRIDGE.bonus > 1) { int insult_bonus = BRIDGE.bonus > 2 ? 100 : 50; snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), " %d points above the line for the insult.", insult_bonus); points_above += insult_bonus; } if (BRIDGE.contract >= 6) { int slam_bonus; if (BRIDGE.contract == 6) slam_bonus = vulnerable ? 1000 : 500; else slam_bonus = vulnerable ? 1500 : 750; snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), " %d points for a %s slam%s.", slam_bonus, BRIDGE.contract == 7 ? "grand" : "small", vulnerable ? " while vulnerable" : ""); points_above += slam_bonus; } } else { tricks_above = BRIDGE.contract - tricks; /* Penalty: not vulnerable vulnerable not doubled 50 100 doubled - 1st 100 200 doubled - 2nd,3rd 200 ea 300 ea doubled - 4th+ 300 ea 300 ea redoubled 2x doubled 2x doubled */ if (BRIDGE.bonus == 1) points_above = tricks_above * (vulnerable ? 100 : 50); else { points_above = tricks_above * (vulnerable ? 200 : 100); if (tricks_above > 1) points_above += (tricks_above - 1) * 100; if (tricks_above > 3) points_above += (tricks_above - 3) * (vulnerable ? 0 : 100); if (BRIDGE.bonus == 4) points_above *= 2; } snprintf(buf2 + strlen(buf2), sizeof(buf2) - strlen(buf2), " %d points above for setting by %d tricks%s%s.", points_above, tricks_above, bonus_text, vulnerable ? ", vulnerable" : ""); } BRIDGE.points_above_line[winning_team] += points_above; BRIDGE.points_below_line[BRIDGE.game_count][winning_team] += points_below; if (tricks >= BRIDGE.contract) snprintf(buf, sizeof(buf), "%s made the bid and earned %d|%d points.", get_player_name(BRIDGE.declarer), points_above, points_below); else snprintf(buf, sizeof(buf), "%s went set, giving up %d points.", get_player_name(BRIDGE.declarer), points_above); /* TODO: points for honors */ if (BRIDGE.points_below_line[BRIDGE.game_count][winning_team] >= 100) { if (BRIDGE.vulnerable[winning_team]) { /* they've won a rubber */ int rubber_bonus = BRIDGE.vulnerable[1 - winning_team] ? 500 : 700; BRIDGE.points_above_line[winning_team] += rubber_bonus; for (team = 0; team < 2; team++) { for (g = 0; g <= BRIDGE.game_count; g++) { BRIDGE.points_above_line[team] += BRIDGE. points_below_line[g][team]; BRIDGE.points_below_line[g][team] = 0; } } BRIDGE.game_count = 0; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " They won a %d-point rubber.", rubber_bonus); /* right now, we jsut go right on into the next rubber with a running score. Instead, this should be the end of a game */ } else { /* they've won their first game of the rubber */ BRIDGE.game_count++; BRIDGE.vulnerable[winning_team] = 1; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " They won a game."); } } /* TODO: vulnerable, etc. */ set_global_message("", "%s", buf); set_global_message("Hand Score", buf2); bridge_set_score_message(); BRIDGE.declarer = BRIDGE.dummy = -1; BRIDGE.dummy_revealed = 0; BRIDGE.contract = 0; }
/* This function is extra-ordinarily overcomplicated. I hate string handling... */ static void send_cumulative_scores(void) { char buf[4096]; int buf_len = 0, r; int widths[game.num_teams]; if (!game.cumulative_scores) return; /* First, put up the list of players/teams and calculate the string width of each. This is a pretty complicated process... */ buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, " # "); memset(widths, 0, sizeof(widths)); teams_iterate(t) { int num = 0; player_t p; char *orig = buf + buf_len; for (p = 0; p < game.num_players; p++) { if (game.players[p].team == t) { if (num != 0) { buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "/"); } buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "%s", get_player_name(p)); num++; } } widths[t] = strlen(orig); if (t != game.num_teams - 1) { buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, " "); } } teams_iterate_end; buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "\n"); for (r = 0; r < game.hand_num + 1; r++) { buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "%2d ", r + 1); teams_iterate(t) { int score = game.teams[t].scores[r].score; int iw = int_len(score); int extra = widths[t] - iw; /* this overcomplicated bit of hackery is intended to center the score under the name. Unfortunately, it assumes the number isn't longer than 3 characters. */ buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "%*s%*d%*s%s", extra / 2, "", iw, score, (extra + 1) / 2, "", (t == game.num_teams - 1) ? "" : " "); } teams_iterate_end; buf_len += snprintf(buf + buf_len, sizeof(buf) - buf_len, "\n"); } set_global_message("Scores", "%s", buf); }