1 /* NetHack 3.6 winstr.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */
2 /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "NH:sys/amiga/windefs.h"
6 #include "NH:sys/amiga/winext.h"
7 #include "NH:sys/amiga/winproto.h"
9 /* Put a string into the indicated window using the indicated attribute */
12 amii_putstr(window, attr, str)
20 register struct amii_WinDesc *cw;
22 int i, j, n0, bottom, totalvis, wheight;
23 static int wrapping = 0;
25 /* Always try to avoid a panic when there is no window */
26 if (window == WIN_ERR) {
28 if (window == WIN_ERR)
29 window = WIN_BASE = amii_create_nhwindow(NHW_BASE);
32 if (window == WIN_ERR || (cw = amii_wins[window]) == NULL) {
33 iflags.window_inited = 0;
34 panic(winpanicstr, window, "putstr");
41 amiIDisplay->lastwin = window; /* do we care??? */
43 /* NHW_MENU windows are not opened immediately, so check if we
44 * have the window pointer yet
48 /* Set the drawing mode and pen colors */
49 SetDrMd(w->RPort, JAM2);
50 amii_sethipens(w, cw->type, attr);
51 } else if (cw->type != NHW_MENU && cw->type != NHW_TEXT) {
52 panic("NULL window pointer in putstr 2: %d", window);
55 /* Okay now do the work for each type */
62 /* 8 for --more--, 1 for preceeding sp, 1 for putstr pad */
66 /* There is a one pixel border at the borders, so subtract two */
67 bottom = amii_msgborder(w);
69 wheight = (w->Height - w->BorderTop - w->BorderBottom - 3)
72 if (scrollmsg || wheight > 1)
75 amii_scrollmsg(w, cw);
79 strncpy(toplines, str, TBUFSZ);
80 toplines[TBUFSZ - 1] = 0;
82 /* For initial message to be visible, we need to explicitly position
84 * cursor. This flag, cw->curx == -1 is set elsewhere to force the
85 * cursor to be repositioned to the "bottom".
88 amii_curs(WIN_MESSAGE, 1, bottom);
92 /* If used all of history lines, move them down */
93 if (cw->maxrow >= iflags.msg_history) {
96 memcpy(cw->data, &cw->data[1],
97 (iflags.msg_history - 1) * sizeof(char *));
98 cw->data[iflags.msg_history - 1] =
99 (char *) alloc(strlen(toplines) + 5);
100 strcpy(cw->data[i = iflags.msg_history - 1] + SOFF
104 /* Otherwise, allocate a new one and copy the line in */
105 cw->data[cw->maxrow] = (char *) alloc(strlen(toplines) + 5);
106 strcpy(cw->data[i = cw->maxrow++] + SOFF + (scrollmsg != 0),
109 cw->data[i][SEL_ITEM] = 1;
110 cw->data[i][VATTR] = attr + 1;
114 cw->data[i][2] = (cw->wflags & FLMSG_FIRST) ? '>' : ' ';
117 str = cw->data[i] + SOFF;
118 if (cw->curx + strlen(str) >= (cw->cols - fudge)) {
120 char *ostr = (char *) str;
123 while (cw->curx + strlen(str) >= (cw->cols - fudge)) {
124 for (p = ((char *) &str[cw->cols - 1 - cw->curx]) - fudge;
125 !isspace(*p) && p > str;)
131 /* p = (char *)&str[ cw->cols ]; */
136 i = (long) p - (long) str;
137 outsubstr(cw, (char *) str, i, fudge);
146 outsubstr( cw, "+", 1, fudge );
151 amii_scrollmsg(w, cw);
152 amii_cl_end(cw, cw->curx);
157 outsubstr(cw, "+", 1, fudge);
160 while (isspace(*str))
162 outsubstr(cw, (char *) str, i = strlen((char *) str), fudge);
164 amii_cl_end(cw, cw->curx);
167 outsubstr(cw, (char *) str, i = strlen((char *) str), fudge);
169 amii_cl_end(cw, cw->curx);
171 cw->wflags &= ~FLMSG_FIRST;
174 totalvis = CountLines(window);
175 SetPropInfo(w, &MsgScroll,
176 (w->Height - w->BorderTop - w->BorderBottom)
177 / w->RPort->TxHeight,
180 i = strlen(toplines + SOFF);
181 cw->maxcol = max(cw->maxcol, i);
182 cw->vwy = cw->maxrow;
186 if (cw->data[cw->cury] == NULL)
187 panic("NULL pointer for status window");
188 ob = &cw->data[cw->cury][j = cw->curx];
192 /* Display when beam at top to avoid flicker... */
194 Text(w->RPort, (char *) str, strlen((char *) str));
195 if (cw->cols > strlen(str))
196 TextSpaces(w->RPort, cw->cols - strlen(str));
198 (void) strncpy(cw->data[cw->cury], str, cw->cols);
199 cw->data[cw->cury][cw->cols - 1] = '\0'; /* null terminate */
200 cw->cury = (cw->cury + 1) % 2;
206 if (cw->type == NHW_BASE && wrapping) {
207 amii_curs(window, cw->curx + 1, cw->cury);
208 TextSpaces(w->RPort, cw->cols);
209 if (cw->cury < cw->rows) {
210 amii_curs(window, cw->curx + 1, cw->cury + 1);
211 TextSpaces(w->RPort, cw->cols);
215 amii_curs(window, cw->curx + 1, cw->cury);
216 Text(w->RPort, (char *) str, strlen((char *) str));
218 /* CR-LF is automatic in these windows */
220 if (cw->type == NHW_BASE && cw->cury >= cw->rows) {
229 /* always grows one at a time, but alloc 12 at a time */
231 if (cw->cury >= cw->rows || !cw->data) {
234 /* Allocate 12 more rows */
236 tmp = (char **) alloc(sizeof(char *) * cw->rows);
238 /* Copy the old lines */
239 for (i = 0; i < cw->cury; i++)
240 tmp[i] = cw->data[i];
249 /* Null out the unused entries. */
250 for (i = cw->cury; i < cw->rows; i++)
255 panic("no data storage");
257 /* Shouldn't need to do this, but... */
259 if (cw->data && cw->data[cw->cury]) {
260 free(cw->data[cw->cury]);
261 cw->data[cw->cury] = NULL;
264 n0 = strlen(str) + 1;
265 cw->data[cw->cury] = (char *) alloc(n0 + SOFF);
267 /* avoid nuls, for convenience */
268 cw->data[cw->cury][VATTR] = attr + 1;
269 cw->data[cw->cury][SEL_ITEM] = 0;
270 Strcpy(cw->data[cw->cury] + SOFF, str);
274 if (++cw->cury > cw->maxrow)
275 cw->maxrow = cw->cury;
279 panic("Invalid or unset window type in putstr()");
284 amii_scrollmsg(w, cw)
285 register struct Window *w;
286 register struct amii_WinDesc *cw;
290 bottom = amii_msgborder(w);
293 (w->Height - w->BorderTop - w->BorderBottom - 3) / w->RPort->TxHeight;
296 if (++cw->disprows > wheight) {
298 cw->disprows = 1; /* count this line... */
300 ScrollRaster(w->RPort, 0, w->RPort->TxHeight, w->BorderLeft,
301 w->BorderTop + 1, w->Width - w->BorderRight - 1,
302 w->Height - w->BorderBottom - 1);
304 amii_curs(WIN_MESSAGE, 1, bottom);
314 /* There is a one pixel border at the borders, so subtract two */
315 bottom = w->Height - w->BorderTop - w->BorderBottom - 2;
316 bottom /= w->RPort->TxHeight;
324 register struct amii_WinDesc *cw;
326 struct Window *w = cw->win;
328 if ((cw->wflags & FLMAP_SKIP) == 0) {
332 bottom = amii_msgborder(w);
334 ScrollRaster(w->RPort, 0, w->RPort->TxHeight, w->BorderLeft,
335 w->BorderTop + 1, w->Width - w->BorderRight - 1,
336 w->Height - w->BorderBottom - 1);
337 amii_curs(WIN_MESSAGE, 1, bottom); /* -1 for inner border */
338 Text(w->RPort, "--more--", 8);
340 Text(w->RPort, " --more--", 9);
342 /* Make sure there are no events in the queue */
343 flushIDCMP(HackPort);
345 /* Allow mouse clicks to clear --more-- */
347 if (lastevent.type == WEKEY && lastevent.un.key == '\33')
348 cw->wflags |= FLMAP_SKIP;
351 amii_curs(WIN_MESSAGE, 1, 0);
352 amii_cl_end(cw, cw->curx);
357 outsubstr(cw, str, len, fudge)
358 register struct amii_WinDesc *cw;
363 struct Window *w = cw->win;
366 /* Check if this string and --more-- fit, if not,
367 * then put out --more-- and wait for a key.
369 if ((len + fudge) + cw->curx >= cw->cols) {
373 /* Otherwise, move and put out a blank separator */
374 Text(w->RPort, spaces, 1);
379 Text(w->RPort, str, len);
382 /* Put a graphics character onto the screen */
385 amii_putsym(st, i, y, c)
391 Text(amii_wins[st]->win->RPort, &c, 1);
394 /* Add to the last line in the message window */
400 register struct amii_WinDesc *cw = amii_wins[WIN_MESSAGE];
403 if (cw->curx == cw->cols - 1)
404 amii_putstr(WIN_MESSAGE, 0, "");
405 amii_putsym(WIN_MESSAGE, cw->curx + 1, amii_msgborder(cw->win), *s++);
418 while (nr > sizeof(spaces) - 1) {
419 Text(rp, spaces, (long) sizeof(spaces) - 1);
420 nr -= sizeof(spaces) - 1;
423 Text(rp, spaces, (long) nr);
429 /* ignore for now. I think this will be done automatically by
430 * the code writing to the message window, but I could be wrong.
435 amii_doprev_message()
437 struct amii_WinDesc *cw;
441 if (WIN_MESSAGE == WIN_ERR || (cw = amii_wins[WIN_MESSAGE]) == NULL
442 || (w = cw->win) == NULL) {
443 panic(winpanicstr, WIN_MESSAGE, "doprev_message");
446 /* When an interlaced/tall screen is in use, the scroll bar will be there
448 /* Or in some other cases as well */
451 struct PropInfo *pip;
452 int hidden, topidx, i, total, wheight;
454 for (gd = w->FirstGadget; gd && gd->GadgetID != 1;)
458 pip = (struct PropInfo *) gd->SpecialInfo;
459 wheight = (w->Height - w->BorderTop - w->BorderBottom - 2)
460 / w->RPort->TxHeight;
461 hidden = max(cw->maxrow - wheight, 0);
462 topidx = (((ULONG) hidden * pip->VertPot) + (MAXPOT / 2)) >> 16;
463 for (total = i = 0; i < cw->maxrow; ++i) {
464 if (cw->data[i][1] != 0)
469 topidx -= wheight / 4 + 1;
472 SetPropInfo(w, &MsgScroll, wheight, total, topidx);
473 DisplayData(WIN_MESSAGE, topidx);
481 str = "\0\0No more history saved...";
483 str = cw->data[cw->vwy];
486 amii_curs(WIN_MESSAGE, 1, 0);
487 amii_setdrawpens(amii_wins[WIN_MESSAGE]->win, NHW_MESSAGE);
488 Text(w->RPort, str + SOFF, strlen(str + SOFF));
489 cw->curx = cw->cols + 1;