+ /* One more window */
+ next_win++;
+ }
+ } else
+ /* Parse Args and Prepare the Terminals. Rectangles are specified
+ as Width x Height, right? The game will allow you to have two
+ strips of extra terminals, one on the right and one on the bottom.
+ The map terminal will than fit in as big as possible in the remaining
+ space.
+ Examples:
+ angband -mgcu -- -right 30x27,* -bottom *x7 will layout as
+ Term-0: Map (COLS-30)x(LINES-7) | Term-1: 30x27
+ --------------------------------|----------------------
+ <----Term-3: (COLS-30)x7------->| Term-2: 30x(LINES-27)
+ composband -mgcu -- -bottom *x7 -right 30x27,* will layout as
+ Term-0: Map (COLS-30)x(LINES-7) | Term-2: 30x27
+ |------------------------------
+ | Term-3: 30x(LINES-27)
+ ---------------------------------------------------------------
+ <----------Term-1: (COLS)x7----------------------------------->
+ Notice the effect on the bottom terminal by specifying its argument
+ second or first. Notice the sequence numbers for the various terminals
+ as you will have to blindly configure them in the window setup screen.
+ EDIT: Added support for -left and -top.
+ */
+ {
+ rect_t remaining = rect(0, 0, COLS, LINES);
+ int spacer_cx = 1;
+ int spacer_cy = 1;
+ int next_term = 1;
+ int term_ct = 1;
+
+ for (i = 1; i < argc; i++) {
+ if (streq(argv[i], "-spacer")) {
+ i++;
+ if (i >= argc) {
+ quit("Missing size specifier for -spacer");
+ }
+ sscanf(argv[i], "%dx%d", &spacer_cx, &spacer_cy);
+ } else if (streq(argv[i], "-right") || streq(argv[i], "-left")) {
+ const char *arg, *tmp;
+ bool left = streq(argv[i], "-left");
+ int cx, cys[MAX_TERM_DATA] = { 0 }, ct, j, x, y;
+
+ i++;
+ if (i >= argc) {
+ quit(format("Missing size specifier for -%s", left ? "left" : "right"));
+ }
+
+ arg = argv[i];
+ tmp = strchr(arg, 'x');
+ if (!tmp) {
+ quit(format("Expected something like -%s 60x27,* for two %s hand terminals of 60 columns, the first 27 lines and the second whatever is left.", left ? "left" : "right", left ? "left" : "right"));
+ }
+ cx = atoi(arg);
+ remaining.cx -= cx;
+ if (left) {
+ x = remaining.x;
+ y = remaining.y;
+ remaining.x += cx;
+ } else {
+ x = remaining.x + remaining.cx;
+ y = remaining.y;
+ }
+ remaining.cx -= spacer_cx;
+ if (left) {
+ remaining.x += spacer_cx;
+ }
+
+ tmp++;
+ ct = _parse_size_list(tmp, cys, MAX_TERM_DATA);
+ for (j = 0; j < ct; j++) {
+ int cy = cys[j];
+ if (y + cy > remaining.y + remaining.cy) {
+ cy = remaining.y + remaining.cy - y;
+ }
+ if (next_term >= MAX_TERM_DATA) {
+ quit(format("Too many terminals. Only %d are allowed.", MAX_TERM_DATA));
+ }
+ if (cy <= 0) {
+ quit(format("Out of bounds in -%s: %d is too large (%d rows max for this strip)",
+ left ? "left" : "right", cys[j], remaining.cy));
+ }
+ data[next_term++].r = rect(x, y, cx, cy);
+ y += cy + spacer_cy;
+ term_ct++;
+ }
+ } else if (streq(argv[i], "-top") || streq(argv[i], "-bottom")) {
+ const char *arg, *tmp;
+ bool top = streq(argv[i], "-top");
+ int cy, cxs[MAX_TERM_DATA] = { 0 }, ct, j, x, y;
+
+ i++;
+ if (i >= argc) {
+ quit(format("Missing size specifier for -%s", top ? "top" : "bottom"));
+ }
+
+ arg = argv[i];
+ tmp = strchr(arg, 'x');
+ if (!tmp) {
+ quit(format("Expected something like -%s *x7 for a single %s terminal of 7 lines using as many columns as are available.", top ? "top" : "bottom", top ? "top" : "bottom"));
+ }
+ tmp++;
+ cy = atoi(tmp);
+ ct = _parse_size_list(arg, cxs, MAX_TERM_DATA);
+
+ remaining.cy -= cy;
+ if (top) {
+ x = remaining.x;
+ y = remaining.y;
+ remaining.y += cy;
+ } else {
+ x = remaining.x;
+ y = remaining.y + remaining.cy;
+ }
+ remaining.cy -= spacer_cy;
+ if (top) {
+ remaining.y += spacer_cy;
+ }
+
+ tmp++;
+ for (j = 0; j < ct; j++) {
+ int cx = cxs[j];
+ if (x + cx > remaining.x + remaining.cx) {
+ cx = remaining.x + remaining.cx - x;
+ }
+ if (next_term >= MAX_TERM_DATA) {
+ quit(format("Too many terminals. Only %d are allowed.", MAX_TERM_DATA));
+ }
+ if (cx <= 0) {
+ quit(format("Out of bounds in -%s: %d is too large (%d cols max for this strip)",
+ top ? "top" : "bottom", cxs[j], remaining.cx));
+ }
+ data[next_term++].r = rect(x, y, cx, cy);
+ x += cx + spacer_cx;
+ term_ct++;
+ }
+ }
+ }
+
+ /* Map Terminal */
+ if (remaining.cx < MIN_TERM0_COLS || remaining.cy < MIN_TERM0_LINES) {
+ quit_fmt("Failed: %s needs an %dx%d map screen, not %dx%d", std::string(VARIANT_NAME).c_str(), MIN_TERM0_COLS, MIN_TERM0_LINES, remaining.cx, remaining.cy);
+ }
+ data[0].r = remaining;
+ term_data_init(&data[0]);
+ angband_term[0] = game_term;
+
+ /* Child Terminals */
+ for (next_term = 1; next_term < term_ct; next_term++) {
+ term_data_init(&data[next_term]);
+ angband_term[next_term] = game_term;
+ }