/* File: main-vme.c */ /* Purpose: Support for "Vax Angband" */ /* This is MAIN-VME C for VM/ESA machines. First enable definition of VM in file "h-config.h" You need to unpack archive EXT-VM VMARC . To do that first set fixed file record length: 'COPYFILE EXT-VM VMARC A = = = ( REC F' Then unpack: VMARC UNPACK EXT-VM VMARC A ( if you don't have archivator vmarc, there is many places where you get it, i got it from cc1.kuleuven.ac.be ) Then read MAKEFILE EXEC. It contains all neccessary information to compile Angband. EXT-VM VMARC content: MAKEFILE EXEC VMSERV TXTLIB CNSHND ASSEMBLE You will need about 3-4 MB free disk space to compile it. If you have any problems, mail to SM20616@vm.lanet.lv or SD30066@vm.lanet.lv A large amount of this file appears to be a complete hack, but what can you expect from a system designed for the Vax... :-) */ #include "angband.h" #if defined(USE_VME) || defined(VM) /* * Convert EBCDIC to ASCII */ char e2a[]= { 0x00,0x01,0x02,0x03,0x1A,0x09,0x1A,0x7F,0x1A,0x1A,0x1A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x1A,0x0A,0x08,0x1A,0x18,0x19,0x1A,0x1A,0x1C,0x1D,0x1E,0x1F, 0x1A,0x1A,0x1C,0x1A,0x1A,0x0A,0x17,0x1B,0x1A,0x1A,0x1A,0x1A,0x1A,0x05,0x06,0x07, 0x1A,0x1A,0x16,0x1A,0x1A,0x1E,0x1A,0x04,0x1A,0x1A,0x1A,0x1A,0x14,0x15,0x1A,0x1A, 0x20,0xA6,0xE1,0x80,0xEB,0x90,0x9F,0xE2,0xAB,0x8B,0x9B,0x2E,0x3C,0x28,0x2B,0x7C, 0x26,0xA9,0xAA,0x9C,0xDB,0xA5,0x99,0xE3,0xA8,0x9E,0x21,0x24,0x2A,0x29,0x3B,0x5E, 0x2D,0x2F,0xDF,0xDC,0x9A,0xDD,0xDE,0x98,0x9D,0xAC,0xBA,0x2C,0x25,0x5F,0x3E,0x3F, 0xD7,0x88,0x94,0xB0,0xB1,0xB2,0xFC,0xD6,0xFB,0x60,0x3A,0x23,0x40,0x27,0x3D,0x22, 0xF8,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x96,0xA4,0xF3,0xAF,0xAE,0xC5, 0x8C,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x97,0x87,0xCE,0x93,0xF1,0xFE, 0xC8,0x7E,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0xEF,0xC0,0xDA,0x5B,0xF2,0xF9, 0xB5,0xB6,0xFD,0xB7,0xB8,0xB9,0xE6,0xBB,0xBC,0xBD,0x8D,0xD9,0xBF,0x5D,0xD8,0xC4, 0x7B,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0xCB,0xCA,0xBE,0xE8,0xEC,0xED, 0x7D,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0xA1,0xAD,0xF5,0xF4,0xA3,0x8F, 0x5C,0xE7,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0xA0,0x85,0x8E,0xE9,0xE4,0xD1, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xB3,0xF7,0xF0,0xFA,0xA7,0xFF }; /* * Convert ASCII to EBCDIC */ char a2e[]= { 0x00,0x01,0x02,0x03,0x37,0x2D,0x2E,0x2F,0x16,0x05,0x25,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x3C,0x3D,0x32,0x26,0x18,0x19,0x3F,0x27,0x22,0x1D,0x35,0x1F, 0x40,0x5A,0x7F,0x7B,0x5B,0x6C,0x50,0x7D,0x4D,0x5D,0x5C,0x4E,0x6B,0x60,0x4B,0x61, 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0x7A,0x5E,0x4C,0x7E,0x6E,0x6F, 0x7C,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6, 0xD7,0xD8,0xD9,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xAD,0xE0,0xBD,0x5F,0x6D, 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96, 0x97,0x98,0x99,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xC0,0x4F,0xD0,0xA1,0x07, 0x00,0x01,0x02,0x03,0x37,0x2D,0x2E,0x2F,0x16,0x05,0x25,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x3C,0x3D,0x32,0x26,0x18,0x19,0x3F,0x27,0x22,0x1D,0x35,0x1F, 0x40,0x5A,0x7F,0x7B,0x5B,0x6C,0x50,0x7D,0x4D,0x5D,0x5C,0x4E,0x6B,0x60,0x4B,0x61, 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0x7A,0x5E,0x4C,0x7E,0x6E,0x6F, 0x7C,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6, 0xD7,0xD8,0xD9,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xAD,0xE0,0xBD,0x5F,0x6D, 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96, 0x97,0x98,0x99,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xC0,0x4F,0xD0,0xA1,0x07 }; /* * System headers (already included by "angband.h" XXX XXX XXX) */ #include #include #include /* Some prototypes and definitions */ #define FIELD_SY 1 #define FIELD_SX 80 #define FIELD_EY 2 #define FIELD_EX 10 void GetAddr( int,int,char * ); void InitConsole(); void TerminateConsole(); void ResetScrBuf(); void AddScrBuf(char *,int); char InKey(); char InKeyBuf(); void ScreenClear(); void ResetDISP(); int kbhit(); void ShowLine(int y,int x,int len); void LoadProfile(); /* Changed lines marker. */ char DISP[26]; /* Max rows & columns number in screen (note that in older version ** than 2.7.9 we needed 25 lines, though 24th was unused. So it is set ** to 25 although screen actually has only 24 lines. (we just used to ** transfer 25th line into 24th. ** But in new version we no longer use it. */ int rows, cols; /* Game cursor position on screen */ int curx=1; int cury=1; /* * Virtual Screen */ byte VirtualScreen[2048]; byte ScreenAttr[2048]; /* * This array is used for "wiping" the screen, initialized in "init_wat()" */ byte wiper[256]; /* * The main screen */ static term term_screen_body; /* Update line on screen. ** Actually just set flag that we should update it. */ void ScreenUpdateLine(int line) { DISP[line+1]=1; } /* * Clear the whole screen */ void ScreenClear(void) { int iy; for (iy = 0; iy < rows; iy++) { memcpy(VirtualScreen + (iy*cols), wiper, cols); memset(ScreenAttr + (iy*cols), 0xF1, cols); ScreenUpdateLine(iy); } } /* * Nuke a Term */ static void Term_nuke_vm(term *t) { TerminateConsole(); puts("Console has been terminated(nuke)."); } /* * Move the cursor */ static errr Term_curs_vm(int x, int y, int z) { /* Hack: mark line cursor was at as changed to ensure that old ** cursor would be removed. */ DISP[cury]=1; curx=x+1; cury=y+1; return (0); } /* * The Angband color table * * Comment: White has been changed to blue to make screen look better. * Green and Light Green are exchanged for the same reason. * -0x80 means changing to bold font. * * Color Table: * Dark to Blue, White to Blue, Slate to Blue, Orange to Pink, * Red to Red, Green to GreenB, Blue to BlueB, Umber to Yellow, * Gray to Blue, Light White to WhiteB, Violet to PinkB, Yellow to Yellow * Light colors: Red to RedB,Green to Green,Blue to Cyan, Umber to YellB */ static const byte vm_color[] = { 0xF1, 0xF1, 0xF1, 0xF3, 0xF2, 0xF4-0x80, 0xF1-0x80, 0xF6, 0xF1, 0xF7-0x80, 0xF3-0x80, 0xF6, 0xF2-0x80, 0xF4, 0xF5, 0xF6-0x80 }; /* * Place some text on the screen using an attribute */ static errr Term_text_vm(int x, int y, int n, byte a, cptr s) { register int i; register byte attr; register byte *dest; register byte *dest2; /* Attribute... */ attr = vm_color[a&0x0F]; /* Paranoia */ if (n > cols - x) n = cols - x; /* Access the destination */ dest = VirtualScreen + ((cols * y) + x); dest2 = ScreenAttr + ((cols * y) + x); /* Virtually write the string */ for (i = 0; (i < n) && s[i]; i++) { *dest++ = s[i]; *dest2++ = attr; } /* Dump the line */ ScreenUpdateLine(y); /* Success */ return (0); } /* * Erase part of line. */ static errr Term_wipe_vm(int x, int y, int w) { /* Paranoia -- Verify the dimensions */ if (cols < (w+x)) w = (cols-x); /* Wipe part of the virtual screen, and update */ memcpy(VirtualScreen + (y*cols + x), wiper, w); memset(ScreenAttr + (y*cols + x), 0xF1, w); ScreenUpdateLine(y); /* Success */ return (0); } /* * Handle special request. */ static errr Term_xtra_vm(int n, int v) { int i, j; char tmp; /* Analyze the request */ switch (n) { /* Make a noise */ case TERM_XTRA_NOISE: /* No noises here! :) */ return( 0 ); /* Wait for a single event */ case TERM_XTRA_EVENT: /* No wait key press check */ if (!v && !kbhit()) return( 1 ); /* Wait for a keypress */ i = getkey(); /* Save keypress */ Term_keypress(i); /* Success */ return( 0 ); case TERM_XTRA_CLEAR: ScreenClear(); return(0); #if 0 case TERM_XTRA_FROSH: ScreenUpdateLine(VirtualScreen + (cols*v), v); return(0); #endif case TERM_XTRA_FLUSH: /* Flush keys */ while (1) { tmp=getkeybuf(); if (!tmp) break; Term_keypress(tmp); } /* Success */ return(0); } /* Unknown request */ return (1); } /* * Initialize the VM/CNSconsole. */ errr init_vme() { register i; term *t = &term_screen_body; short blank = ' '; static int done = FALSE; /* Paranoia -- Already done */ if (done) return (-1); /* Build a "wiper line" of blank spaces */ for (i = 0; i < 256; i++) wiper[i] = blank; /* Acquire the size of the screen */ rows = 25; cols = 80; /* Initialize the console */ InitConsole(); /* Wipe the screen */ for (i = 0; i < rows; i++) { /* Wipe that row */ memcpy(VirtualScreen + (i*cols), wiper, cols); memset(ScreenAttr + (i*cols), 0xF1, cols); } /* Erase the screen */ ScreenClear(); /* Initialize the term -- very large key buffer */ term_init(t, cols, rows - 1, 1024); /* Prepare the init/nuke hooks */ t->nuke_hook = Term_nuke_vm; /* Connect the hooks */ t->text_hook = Term_text_vm; t->wipe_hook = Term_wipe_vm; t->curs_hook = Term_curs_vm; t->xtra_hook = Term_xtra_vm; /* Save it */ term_screen = t; /* Activate it */ Term_activate(term_screen); /* Done */ done = TRUE; /* Success */ return 0; } /* Wait for keypress */ int getkey( void ) { return((int)InKey()); } /* Read key buffer if not empty */ int getkeybuf() { return((int)InKeyBuf()); } /*********************************************************************/ /*********************************************************************/ /****************** Actual work with console *********************/ /*********************************************************************/ /* Low-level functions */ int CNSINIT(char *path,int device); int CNSTERM(char *path); int CNSREAD(char *path,char *buffer,int buflen); int CNSWRITE(char *path,char *buffer,int buflen); #define _PF1 (0xF1) #define _PF2 (0xF2) #define _PF3 (0xF3) #define _PF4 (0xF4) #define _PF5 (0xF5) #define _PF6 (0xF6) #define _PF7 (0xF7) #define _PF8 (0xF8) #define _PF9 (0xF9) #define _PF10 (0x7A) #define _PF11 (0x7B) #define _PF12 (0x7C) #define _PF13 (0xC1) #define _PF14 (0xC2) #define _PF15 (0xC3) #define _PF16 (0xC4) #define _PF17 (0xC5) #define _PF18 (0xC6) #define _PF19 (0xC7) #define _PF20 (0xC8) #define _PF21 (0xC9) #define _PF22 (0x4A) #define _PF23 (0x4B) #define _PF24 (0x4C) #define _PA2 (0x6E) #define _PA3 (0x6B) #define _CLEAR (0x60) #define _ENTER (0x7D) extern char cnscrstb[]; /* Hardware 3270 cursor offsets */ /* Console identificator */ char *cons="console"; /* Console interrupt flag; should be set by assembler patch */ int CNSINTR; /* Assembler function prototype; this handles console interrupt */ extern int CNSHD(); /* Buffer for output stream (VM/ESA uses streams to control terminals */ static char * ScrBuf; /* Incoming buffer from console after cnsread */ static char * InBuf; /* User entered command buffer (paranoia: make it so long no one will ** ever run short of it :) */ static char ComBuf[256]; /* Pointer to current position in ComBuf */ static char * ComPtr; /* This array is used to clean up input field. ** Comment: erase everything user entered after we accepted it. */ static char wiping[]= {0,0,0,0,0,0,0,0,0,0,0,0}; /* Flag: should we wipe input field ? */ static int wipe=0; /* Counter: how many times did game checked if we pressed any key. ** Comment: after every 100th we update the screen. ** Comment2: because of slow work with screen it would be _very_ ** unwise to make it more often. */ static int kbhitcount; /* Keep length of collected output stream */ static int BufLen; /* Define array which will be used to bring actual cursor ** (not game cursor!!!) back to the beginning of input field. */ static char CursorHome[]= {0,0,0,0x13}; /* Define array to make fields on the screen. ** Comment: 2 fields: input field(writable), and game field(protected). ** Comment2: We will change PSS settings into dumb repeating of color ** setting if PSS fonts are not abailable. */ static char ScrField[]= {0,0,0,0x29,0x03,0xC0,0xC1,0x42,0xF3,0x43,0xC1,\ 0,0,0,0x29,0x03,0xC0,0x60,0x42,0xF1,0x43,0xC1}; /* Last command user entered (for repeating purposes */ static char LastCmd[256]; /* Array which holds PFkeys definitions */ static char PFcmd[25][80]; /* Actually initialize console ... */ void InitConsole( void ) { /* Use this to activate full screen mode after console has been ** initialized. */ unsigned char init[6] = {0xC2,0x11,0x40,0x40,0,0}; int i; /* Array for checking is PSS fonts are loaded */ char pss[256]; /* Allocate memory */ ScrBuf=malloc(4100); if(ScrBuf==NULL) { puts("Cannot mallocate memory for screen buffer!"); exit(77); } /* Block system standarts... */ system("cp set msg off"); system("cp set emsg off"); system("cp set imsg off"); system("cp term brkkey none"); /* Test PSS */ system("desbuf"); system("query display (stack"); gets(pss); i=1; if(pss[63]!='P') i=0; if(pss[64]!='S') i=0; if(pss[65]!='S') i=0; if(pss[72]!='0') i=0; if(pss[73]!='1') i=0; if(pss[74]!='A') i=0; if(pss[75]!='B') i=0; if(i==0) { /* No PSS. Cannot run without them... */ puts("ERROR: Cannot run without PSS fonts!"); exit(77); } ScrBuf[0]=0xC2; ScrBuf[1]=0; BufLen=1; /* Allocate memory */ InBuf=malloc(200); if(InBuf==NULL) { puts("Cannot mallocate memory for screen buffer!"); exit(77); } /* Okay, lets make some intial assigments */ InBuf[0]=0; ComBuf[0]=0; ComPtr=ComBuf; LastCmd[0]=0; GetAddr(FIELD_SY,FIELD_SX,ScrField); GetAddr(FIELD_EY,FIELD_EX,ScrField+11); GetAddr(FIELD_SY,FIELD_SX+1,wiping); GetAddr(FIELD_SY,FIELD_SX+1,CursorHome); /* Initialize console */ cnsxinit( cons,0x9,1,CNSHD ); /* Activate full-screen mode */ cnswrite( cons,init,6 ); /* No lines on screen were changed */ for(i=1;i<25;i++) DISP[i]=0; /* Corsor home... */ AddScrBuf(CursorHome,sizeof(CursorHome)); /* No console interrupt yet */ CNSINTR=0; /* No check keypresses yet */ kbhitcount=0; /* Let's load 'profile angband' for PFs settings */ LoadProfile(); } void TerminateConsole( void ) { free(ScrBuf); free(InBuf); /* Terminate console */ cnsterm( cons ); /* Restore system defaults. ** Comment: better we should have written them down at start but ** it is reasonably difficult to make, so just set standart values. */ system("cp set msg on"); system("cp set emsg on"); system("cp set imsg on"); system("cp term brkkey pa1"); } /* Reset collected output stream */ void ResetScrBuf() { int i; unsigned char attr; /* Where shall cursor be ? */ GetAddr(cury,curx,ScrBuf+BufLen); BufLen+=3; /* Actually 'make' cursor : underline symbol */ ScrBuf[BufLen++]=0x28; ScrBuf[BufLen++]=0x41; ScrBuf[BufLen++]=0xF4; attr=*(ScreenAttr+(cury-1)*cols+curx-1); ScrBuf[BufLen++]=0x28; ScrBuf[BufLen++]=0x42; ScrBuf[BufLen++]=attr|0x80; ScrBuf[BufLen++]=0x28; ScrBuf[BufLen++]=0x43; if(attr>0x80) ScrBuf[BufLen++]=0xC1; else ScrBuf[BufLen++]=0xC2; ScrBuf[BufLen++]=*(VirtualScreen+(cury-1)*cols+curx-1); ScrBuf[BufLen++]=0x28; ScrBuf[BufLen++]=0x41; ScrBuf[BufLen++]=0x00; ScrBuf[BufLen++]=0x28; ScrBuf[BufLen++]=0x43; ScrBuf[BufLen++]=0xC1; /* Draw screen fields. ** Comment: paranoia, should always be there, but won't be any worse ** if we redraw them. */ memcpy(ScrBuf+BufLen,ScrField,22); if(wipe) { /* If we should wipe input field, let's do it. */ wipe=0; memcpy(ScrBuf+BufLen+22,wiping,sizeof(wiping)); /* Actually write to terminal */ cnswrite(cons,ScrBuf,BufLen+22+sizeof(wiping)); } else { /* Actually write to terminal */ cnswrite(cons,ScrBuf,BufLen+22); } /* Discard old output stream */ ScrBuf[0]=0xC2; ScrBuf[1]=0; BufLen=1; } /* Just add some more to output stream */ void AddScrBuf(char * ptr,int len) { /* Stream cannot be longer than 4k, so reset it */ if (len+BufLen>4000) ResetScrBuf(); memcpy(ScrBuf+BufLen,ptr,len); BufLen+=len; } /* Calculate codes for cursor setting and write them down into *stream. ** Comment: system has _really crazy tables for this calculation so ** we need function for this. */ void GetAddr( int y,int x,char *stream ) { int sx,sy,len; len = y * 80 + x - 81; sx = len & 0x3F; sy = len >> 6; *stream++ = 0x11; /* Use standart array for cursor offsets (VMSERV TXTLIB) */ *stream++ = cnscrstb[sy]; *stream = cnscrstb[sx]; } /* Okay, program requested pressed key, let's return it */ char InKey() { char ret; char * info; int i; char *ptr,*ptrs; int PF; int prev; /* If we didn't finish previous line user entered just return ** next symbol. ** Comment: unlikely IBM PC and others user may enter string ** of any length (limited by input field length to 9 ** symbols) and only them by pressing ENTER key or ** functional key make real console interrupt. ** So we should handle everything user entered. */ if (*ComPtr) { ret=*ComPtr; ComPtr++; return(ret); } /* If we get here than user command buffer is empty and we have ** actually wait for new command. */ /* Okay, update screen before :) */ ResetDISP(); /* Well, now wait till user enters something and read it. */ cnsread(cons,InBuf,200); /* Oh, we already handling interrupt so, reset interrupt flag */ CNSINTR=0; /* No previous cmd inserted yet */ prev=0; /* User pressed CLEAR key. Redraw all screen then. */ if (*InBuf==0x6D) { /* Hack: mark all lines as changed */ for(i=1;i<26;i++) DISP[i]=1; /* Cursor home */ AddScrBuf(CursorHome,sizeof(CursorHome)); /* Redraw the whole screen */ ResetDISP(); /* Hack: we should return something, shouldn't we? ** Just return CR. It seems safest. */ return(13); } /* Okay parse stream from console to make string only of ** user's input. */ info=memchr(InBuf,0x1D,200); info+=2; info[9]=0; /* Mark that we should clear input field */ wipe=1; /* Cursor home */ AddScrBuf(CursorHome,sizeof(CursorHome)); /* Pointer to current letter in buffered command set to start */ ComPtr=ComBuf; /* Clear length buffer */ ComBuf[0]=0; switch(*InBuf) { /* PA2 & PA1 */ case 0x6E:; case 0x6C: /* These 2 keys are supposed to mean 'ESC' */ return(27); break; /* Hack: determine which PF key was exactly pressed. */ case _PF1: PF=1; break; case _PF2: PF=2; break; case _PF3: PF=3; break; case _PF4: PF=4; break; case _PF5: PF=5; break; case _PF6: PF=6; break; case _PF7: PF=7; break; case _PF8: PF=8; break; case _PF9: PF=9; break; case _PF10: PF=10; break; case _PF11: PF=11; break; case _PF12: PF=12; break; case _PF13: PF=13; break; case _PF14: PF=14; break; case _PF15: PF=15; break; case _PF16: PF=16; break; case _PF17: PF=17; break; case _PF18: PF=18; break; case _PF19: PF=19; break; case _PF20: PF=20; break; case _PF21: PF=21; break; case _PF22: PF=22; break; case _PF23: PF=23; break; case _PF24: PF=24; break; /* Uh, user pressed ENTER. ** Determine if we should add 'CR' at the end or not ? */ case _ENTER: PF=0; /* Copy entered string into buffer */ strcpy(ComBuf,info); /* Never end strings of length 1 or 0 with CR */ if(strlen(ComBuf)<2) break; /* If string ends with R* or R& add CR */ ptr=info+strlen(info)-1; if(*ptr=='*'||*ptr=='&') { ptr--; if(ptr=info) { if(*ptr=='R') break; if(*ptr=='@'&&ptr==info) break; if(*ptr=='/') { i=0; if(*(ptr-1)!='8') break; if(*(ptr-2)!='1') break; if((ptr-2)!=info) break; i=1; break; } if(!isdigit(*ptr)) { i=0; break; } ptr--; } if(i) ptr=ComBuf+strlen(ComBuf); ptr[0]=13; ptr[1]=0; break; default: PF=0; } /* Okay let's proceed with parsing PFkeys commands */ ptrs=PFcmd[PF]; ptr=ComBuf; /* If key actually was PF and we didn't run into end of PF ** command definition... */ while(*ptrs && PF) { /* If not '\' just copy symbol into buffer */ if(*ptrs!='\\') { *ptr=*ptrs; ptr++; ptrs++; continue; } /* We have discovered '\'. Let's resolve it. */ ptrs++; switch(*ptrs) { /* End of line ? Do nothing then. */ case 0: break; /* User actually wants '\' */ case '\\': *ptr='\\'; ptr++; break; /* User wants his previous command inserted. */ case 'p': /* Set flag that we used previous command */ prev=1; strcpy(ptr,LastCmd); ptr=ComBuf+strlen(ComBuf); break; /* Insert string user actually entered */ case 's': strcpy(ptr,info); ptr=ComBuf+strlen(ComBuf); break; /* User wants 'CR' */ case 'n': *ptr=13; ptr++; break; /* Simulate CTRL key pressing */ case '^': ptrs++; if(!(*ptrs)) break; *ptr=KTRL(*ptrs); ptr++; break; /* ESC */ case 'c': *ptr=27; ptr++; break; /* Hmm, urecognized command. Just copy letter. */ default: *ptr=*ptrs; ptr++; } if(ptrs) ptrs++; } /* Terminate string with 0 if neccessary */ if(PF) *ptr=0; /* Empty string? User probably wants to send CR. */ if(!(*ComBuf)) { return(13); } /* Okay, set pointer to next letter */ ComPtr++; /* Backup last command if not empty */ ptr=ComBuf; /* String still "empty" */ i=1; while((*ptr)&&i) { if((*ptr!=13)&&(*ptr!=' ')&&(*ptr!='27')) i=0; ptr++; } /* Never update previous command if we inserted it. ** Comment: this is to avoid recursively multiplying previous ** commands. */ if((!i)&&(!prev)) strcpy(LastCmd,ComBuf); /* Return something */ return(*ComBuf); } /* Get symbol from buffer if exists */ char InKeyBuf() { char ret; ret=*ComPtr; if(ret) ComPtr++; return(ret); } /* Here we draw all changed lines */ void ResetDISP() { int i; /* No need to redraw screen in near future */ kbhitcount=0; for(i=1;i<25;i++) if (DISP[i]!=0) { /* If line was changed, it won't stay changed any more */ DISP[i]=0; /* We don't want to erase input field definitons from ** screen, so check it carefully. */ switch(i) { case FIELD_SY: ShowLine(i,1,FIELD_SX-1); if (i==FIELD_EY) { ShowLine(i,FIELD_EX+1,80-FIELD_EX); } break; case FIELD_EY: ShowLine(i,FIELD_EX+1,80-FIELD_EX); break; default: ShowLine(i,1,80); } } /* Okay, actually show something */ ResetScrBuf(); } /* Did user press something? */ int kbhit() { kbhitcount++; if (kbhitcount>99) { /* We waited long enough, time to redraw screen. ** Comment: during sleep every 100th turn is shown. */ kbhitcount=0; ResetDISP(); } return(CNSINTR); } /* Let's show requested line(or part of it). */ void ShowLine(int y,int x,int len) { char slbuf[512]; char *ptr,*scr,*attr; int i; unsigned char curattr; ptr=slbuf+3; /* Hack: was used for older version to place 25th string on ** 24th. */ if (y<25) GetAddr(y,x,slbuf); else GetAddr(24,x,slbuf); /* Set some adresses */ curattr=0; scr=VirtualScreen+(y-1)*cols+x-1; attr=ScreenAttr+(y-1)*cols+x-1; /* Let's proceed with string. */ for(i=0;i0x80) *ptr++=0xC1; else *ptr++=0xC2; } /* Color has changed ? Let's change it. */ if(((*attr)&0x7F)!=(curattr&0x7F)) { *ptr++=0x28; *ptr++=0x42; if(*attr>0x80) *ptr++=*attr; else *ptr++=*attr+0x80; } curattr=*attr; } *ptr++=*scr; scr++; attr++; } /* Add string to output stream */ AddScrBuf(slbuf,ptr-slbuf); } void LoadProfile( void ) { FILE *fp; char line[128],*ptr,*pfptr,*p; int pf,i; for( i = 1 ; i <= 24 ; i++ ) strcpy( PFcmd[i],"\\s" ); fp = fopen( "PROFILE ANGBAND","r" ); if( !fp ) return; { while( fgets( line,128,fp ) ) { if( *line == '#' ) continue; ptr = strstr( line,"PF" ); if( !ptr ) continue; ptr += 2; p = ptr; while( isdigit( *p ) ) ++p; *p++ = 0; pf = atoi( ptr ); if( pf < 1 || pf > 24 ) continue; ptr = strchr( p,'"' ); ++ptr; p = strchr( ptr,'"' ); if( !p ) { puts( "'\"' missing in PROFILE ANGBAND." ); continue; } *p = 0; strcpy( PFcmd[pf],ptr ); } } } /* ** ** File descriptor emulation for VM/ESA ** ** */ #include #include #include "fcntl.h" static FILE *file_descriptors[40]; int open( char *name, int flags, int mode ) { char fmode[16]; FILE *fp; int i; strcpy( fmode,"rb" ); if( (flags & O_WRONLY) || (flags & O_RDWR) ) strcpy( fmode,"wb+" ); fp = fopen( name,fmode ); if( !fp ) return( -1 ); for( i = 1 ; i < 40 ; i++ ) if( !file_descriptors[i] ) { file_descriptors[i] = fp; return( i ); } return( -1 ); } void close( int fd ) { fclose( file_descriptors[fd] ); } int read( int fd,char *buff,int bytes ) { return( fread( buff,1,bytes,file_descriptors[fd] ) ); } int write( int fd,char *buff,int bytes ) { return( fwrite( buff,1,bytes,file_descriptors[fd] ) ); } long lseek( int fd,long pos,int set ) { return( fseek( file_descriptors[fd],pos,set ) ); } void unlink( char *filename ) { remove( filename ); } #endif /* USE_VME */