/* * WND.C. Sis„lt„„ toisen osan muutokset (wprintfx, uusi vram jne.) * * (c) 1991 Harri Talvitie * */ #include #include #include #include #include "wnd.h" static void add_list(WND *wnd); static void remove_list(WND *wnd); WND *listhead = NULL; WND *listtail = NULL; /* Reunatyypit: */ static struct { int nw, ne, se, sw, side, side2, line, line2; } brd[] = { {218,191,217,192,179,179,196,196}, /* Border type 00 : single line */ {201,187,188,200,186,186,205,205}, /* Border type 01 : double line */ {214,183,189,211,186,186,196,196}, /* Border type 02 : double top */ {213,184,190,212,179,179,205,205}, /* Border type 03 : double side */ {194,194,217,192,179,179,196,196}, /* Border type 04 : pulldown */ {195,180,217,192,179,179,196,196}, /* Border type 05 : roikkuva */ {195,194,217,192,179,179,196,196}, /* Border type 06 : vasen roik. */ {194,180,217,192,179,179,196,196}, /* Border type 07 : oikea roik. */ {194,180,217,193,179,179,196,196}, /* Border type 08 : spec 1 */ {194,191,180,193,179,179,196,196}, /* Border type 09 : spec 2 */ {218,183,188,212,179,186,196,205}, /* Border type 10 : right & bot */ {214,191,190,200,186,179,196,205}, /* Border type 11 : right & bot */ {201,187,188,200,176,176,176,176}, /* Border type 12 : light block */ { 43, 43, 43, 43,124,124, 45, 45}, /* Border type 13 : vanilla */ {177,177,177,177,177,177,177,177} /* Border type 14 : med. block */ }; WND *wdef(int x, int y, int w, int h, int border) /* m„„ritell„„n ikkuna */ { WND *wnd; wnd = (WND *)malloc(sizeof(WND)); /* luodaan uusi window-template */ XC = x; /* x-koordinaati */ YC = y; /* y-koordinaati */ WC = w; /* leveys */ HC = h; /* korkeus */ BORDER = border; COL = BRDCOL = TTLCOL = RVRCOL = TXTCOL = 7; VISIBLE = BTYPE = NX = NY = 0; PREV = NEXT = NULL; FHEAD = FTAIL = 0; TITLE = ""; if (BORDER == FALSE) { XC--; YC--; HC+=2; WC+=2; } if ( (BUF = (char *)malloc( WC * HC * 2) ) == NULL) { printf("Memory allocation error\n"); return NULL; } add_list(wnd); return wnd; } void wcol(WND *wnd, int where, int col) /* v„rit */ { if (where == ALL) { COL = col; wnd->col[BRD] = col; wnd->col[TTL] = col; wnd->col[RVR] = col; wnd->col[TXT] = col; } else if (where == TXT) { COL = col; wnd->col[where] = col; } else wnd->col[where] = col; } void wopen(WND *wnd) /* avataan ja piirret„„n ikkuna */ { vram(wnd, SAVE); VISIBLE = TRUE; if (wnd->col[TXT] >= TRN) paint_att(XC+1, YC+1, WC-2, HC-2, wnd->col[TXT]-TRN); else paint_chr(XC+1, YC+1, WC-2, HC-2, wnd->col[TXT], 32); if (BORDER == TRUE) wframe(wnd); } void wdraw(WND *wnd) { paint_chr(XC+1, YC+1, WC-2, HC-2, COL, 32); if (BORDER == TRUE) wframe(wnd); } void wframe(WND *wnd) /* reunan ja otsikon piirto */ { int i; for (i=1;i+1title) dtitle(wnd); } void wclose(WND *wnd) /* suljetaan ja poistetaan koko ikkuna */ { vram(wnd, RESTORE); free(BUF); remove_list(wnd); free(wnd); VISIBLE = FALSE; } void wtitle(WND *wnd, char *txt) { TITLE = txt; } void wcursor(WND *wnd, int x, int y) { NX = x; NY = y; } void dtitle(WND *wnd) /* Draw title, kirjoittaa otsikon (WTITLE) */ { int i=0, ln=0; char t[81]; strcpy(t, TITLE); ln = strlen(t); if (ln > WC-2) t[WC-2] = '\0'; else i = ((WC-2-ln) / 2 ); print(XC+1+i,YC,TTLCOL,t); } void vram(WND *wnd, int stat) { /* ikkunan puskurin k„sittely, tallennus tai palautus */ if (BORDER == TRUE) { if (stat == SAVE) vs(XC, YC, WC, HC, BUF); else vr(wnd, XC, YC, WC, HC, BUF); } else { if (stat == SAVE) vs(XC+1, YC+1, WC-2, HC-2, BUF); else vr(wnd, XC+1, YC+1, WC-2, HC-2, BUF); } } static void add_list(WND *wnd) { if (listtail) { PREV = listtail; listtail->_nx = wnd; } listtail = wnd; if (!listhead) listhead=wnd; } static void remove_list(WND *wnd) { if (NEXT) NEXT->_pv = PREV; if (PREV) PREV->_nx = NEXT; if (listhead == wnd) listhead = NEXT; if (listtail == wnd) listtail = PREV; NEXT = PREV = NULL; } void print(int x, int y, int col, char *ln, ...) { /* tulostetaan koordinaattiin x, y v„rill„ col merkkijono ln */ char dlin[256], *dl = dlin; int far *vbuff = (int far *)VRAM + (y * 80 ) + x; va_list ap; va_start(ap, ln); vsprintf(dlin, ln, ap); va_end(ap); col <<= 8; while (*dl) *(int far *)vbuff++ = *dl++ + col; } void paint_chr(int x, int y, int w, int h, int col, int ch) { /* t„ytet„„n alue x,y,w,h merkill„ ch ja v„rill„ col */ char tmpbuff[81]; int endy = y + h, i; for (i = 0; i < w && i < 80; i++) tmpbuff[i] = ch; tmpbuff[i] = '\0'; while (y < endy) print(x, y++, col, tmpbuff); } void paint_att(int x, int y, int w, int h, int col) { /* t„ytet„„n alue x,y,w,h v„rill„ col, merkit j„„v„t ennalleen */ int endy, sx, endx; for (endy = y + h, endx = x+w; y < endy; y++) for (sx = x; sx < endx; sx++) *((char far *)VRAM + (y * 160) + (sx*2) + 1) = col; } void vs(int x, int y, int w, int h, char *buf) { /* tallennetaan alueen x,y,w,h puskuriosa */ int i = 0, tmpx = x, endx = x + w, endy; for (endy = y + h; y < endy; y++, tmpx = x) while (tmpx < endx) { buf[i] = *((char far *)VRAM + (y * 160 ) + (tmpx * 2)); buf[i+1] = *((char far *)VRAM + (y * 160 ) + (tmpx * 2)+ 1); tmpx++; i += 2; } } void vr(WND *wnd, int x, int y, int w, int h, char *buf) { /* palautetaan alueen x,y,w,h puskuriosa, versio 2 */ int i = 0, tmpx = x, endx = x + w, endy; char *vp; for (endy = y + h; y < endy; y++, tmpx = x) while (tmpx < endx) { if ((vp = (waddr(wnd, tmpx-XC-1, y-YC-1))) != NULL) { *vp = buf[i]; *(vp+1) = buf[i+1]; } else { *((char far *)VRAM + (y * 160) + (tmpx * 2)) = buf[i]; *((char far *)VRAM + (y * 160) + (tmpx * 2) + 1) = buf[i+1]; } tmpx++; i += 2; } } char *waddr(WND *wnd, int x, int y) { WND *nxt = NEXT; char *vp; x += XC+1; y += YC+1; while (nxt) { if (nxt->visible && x >= nxt->x && x <= nxt->x + nxt->w-1) if (y >= nxt->y && y <= nxt->y + nxt->h-1) { x -= nxt->x; y -= nxt->y; vp = (char *) ( (nxt->buf) + (y) * ( nxt->w * 2 ) + (x) * 2 ); return vp; } nxt = nxt->_nx; } return NULL; } void wprint(WND *wnd, int x, int y, int col, char *ln, ...) { /* tulostetaan ikkunaan wnd kohtaan x,y v„rill„ col merkkijono ln */ char *vp; static char dlin[256]; char *dl = dlin; va_list ap; va_start(ap, ln); vsprintf(dlin, ln, ap); va_end(ap); while (*dl) { if ((vp = waddr(wnd, x, y)) != NULL) { *vp = *dl++; *(vp+1) = col; } else putfast(x+XC+1, y+YC+1, col, *dl++); x++; } } void wprintf(WND *wnd, char *ln, ...) { /* tulostetaan ikkunaan wnd merkkijono ln */ int x = NX, y = NY; char *vp; static char dlin[256]; char *dl = dlin; va_list ap; va_start(ap, ln); vsprintf(dlin, ln, ap); va_end(ap); while (*dl) { if (*dl == '\n') { x = 0; y++; dl++; continue; } if ((vp = waddr(wnd, x, y)) != NULL) { *vp = *dl++; *(vp+1) = COL; } else putfast(x+XC+1, y+YC+1, COL, *dl++); x++; } NX = x; NY = y; } void wprintfx(WND *wnd, char *ln, ...) { static char dlin[256]; char *dl = dlin; int x = NX, y = NY; char *vp; va_list ap; va_start(ap, ln); vsprintf(dlin, ln, ap); va_end(ap); while (*dl) { if (*dl == '\n') { x = 0; y++; dl++; if (y+3 > HC) { scroll_up(wnd); y--; } continue; } if (*dl == '\r') { x = 0; dl++; continue; } if (x+3 > WC) { x = 0; y++; if (y+3 > HC) { scroll_up(wnd); y--; } } if ((vp = waddr(wnd, x, y)) != NULL) { *vp = *dl++; /* puskuriin */ *(vp+1) = COL; } else /* muutoin ruudulle */ putfast(x+XC+1, y+YC+1, COL, *dl++); x++; } NX = x; NY = y; } void scroll_up(WND *wnd) { /* vieritet„„n ikkunaa yl”sp„in */ int x, y, cont; if (HC > 1) { for (y = 1; y+2 < HC; y++) { for (x = 0; x+2 < WC; x++) { cont = buffget(wnd, x, y); putwindow(wnd, x, y-1, (cont & 0xff00) >> 8, cont & 0x00ff); } } } for (x = 0; x+2 < WC; x++) putwindow(wnd, x, y-1, wnd->col[TXT], ' '); } void putwindow(WND *wnd, int x, int y, int col, char chr) { /* kirjoitetaan ikkunaan wnd merkki chr v„rill„ col */ char *vp; if ((vp = waddr(wnd, x, y)) != NULL) { *vp = chr; *(vp+1) = col; } else putfast(x+XC+1, y+YC+1, col, chr); } int buffget(WND *wnd, int x, int y) { /* hakee ikkunasta merkin ja sen v„rin */ char *vp; if ((vp = (waddr(wnd, x, y))) != NULL) return *vp + (*(vp+1) << 8); else return (getfast(x+XC+1, y+YC+1)); }