Offset alloc(void) /* return free Offset in nextb */ { int i, j; for (i = bfree; i < nblist; i++) if (blist[i].nextoff == 0) break; if (i == nblist) { blist = (Blockp *) realloc((char *) blist, 2 * nblist * sizeof(Blockp)); if (blist == NULL) { ERROR "can't grow blist for string/macro defns" WARN; done2(2); } nblist *= 2; for (j = i; j < nblist; j++) { blist[j].nextoff = 0; blist[j].bp = 0; } } blist[i].nextoff = -1; /* this block is the end */ bfree = i + 1; if (blist[i].bp == 0) blist[i].bp = (Tchar *) calloc(BLK, sizeof(Tchar)); if (blist[i].bp == NULL) { ERROR "can't allocate memory for string/macro definitions" WARN; done2(2); } nextb = (Offset) i * BLK; return nextb; }
void init2(void) { int i; char buf[100]; for (i = NTRTAB; --i; ) trtab[i] = i; trtab[UNPAD] = ' '; iflg = 0; obufp = obuf; if (TROFF) t_ptinit(); else n_ptinit(); mchbits(); cvtime(); numtabp[PID].val = getpid(); numtabp[HP].val = init = 0; numtabp[NL].val = -1; nfo = 0; copyf = raw = 0; sprintf(buf, ".ds .T %s\n", devname); cpushback(buf); sprintf(buf, ".ds .P %s\n", DWBhomedir); cpushback(buf); numtabp[CD].val = -1; /* compensation */ nx = mflg; frame = stk = (Stack *)setbrk(STACKSIZE); dip = &d[0]; nxf = frame + 1; for (i = 1; i < NEV; i++) /* propagate the environment */ envcopy(&env[i], &env[0]); for (i = 0; i < NEV; i++) { if ((env[i]._word._bufp = (Tchar *)calloc(WDSIZE, sizeof(Tchar))) == NULL) { ERROR "not enough room for word buffers" WARN; done2(1); } env[i]._word._size = WDSIZE; if ((env[i]._line._bufp = (Tchar *)calloc(LNSIZE, sizeof(Tchar))) == NULL) { ERROR "not enough room for line buffers" WARN; done2(1); } env[i]._line._size = LNSIZE; } if ((oline = (Tchar *)calloc(OLNSIZE, sizeof(Tchar))) == NULL) { ERROR "not enough room for line buffers" WARN; done2(1); } olinep = oline; olnsize = OLNSIZE; blockinit(); }
int dosave(void) { int n, selected[1]; struct menulist menu; init_menulist(&menu); add_menuitem(&menu, 1, "Quicksave and exit the game", 'y', FALSE); add_menuitem(&menu, 2, "Abandon this game and delete its save file", '!', FALSE); add_menuitem(&menu, 3, "Continue playing", 'n', FALSE); n = display_menu(menu.items, menu.icount, "Do you want to stop playing?", PICK_ONE, PLHINT_URGENT, selected); free(menu.items); if (n) n = selected[0]; else n = 3; if (n == 3) { if (multi > 0) nomul(0, NULL); } else if (n == 1) { pline("Saving..."); if (dosave0(FALSE)) { program_state.something_worth_saving = 0; u.uhp = -1; /* universal game's over indicator */ terminate(); } else doredraw(); } else if (n == 2) { return done2(); } return 0; }
boolean nh_exit_game(int exit_type) { boolean log_disabled = iflags.disable_log; if (!api_entry_checkpoint()) { /* not sure anything in here can actually call panic */ iflags.disable_log = log_disabled; return TRUE; /* terminate was called, so exit is successful */ } program_state.forced_exit = TRUE; /* clean up after viewing a game replay */ if (program_state.viewing) nh_view_replay_finish(); xmalloc_cleanup(); iflags.disable_log = TRUE; if (program_state.game_running) { switch (exit_type) { case EXIT_REQUEST_SAVE: dosave(); /* will ask "really save?" and, if 'y', eventually call terminate. */ break; case EXIT_FORCE_SAVE: dosave0(TRUE); terminate(); break; case EXIT_REQUEST_QUIT: done2(); break; case EXIT_FORCE_QUIT: done(QUIT); break; /* not reached */ case EXIT_PANIC: /* freeing things should be safe */ freedynamicdata(); dlb_cleanup(); panic("UI problem."); break; } iflags.disable_log = log_disabled; api_exit(); return FALSE; } iflags.disable_log = log_disabled; /* calling terminate() will get us out of nested contexts safely, eg: * UI_cmdloop -> nh_command -> UI_update_screen (problem happens here) -> nh_exit_game * will jump all the way back to UI_cmdloop */ terminate(); api_exit(); /* not reached */ return TRUE; }
void caseev(void) { char *name; int nxev; struct env *np, *op; if (getev(&nxev, &name) == 0) { if (evi == 0) return; nxev = evlist[--evi]; goto e1; } if (xflag == 0 && ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ))) goto cannot; if (evi >= evlsz) { evlsz = evi + 1; if ((evlist = realloc(evlist, evlsz * sizeof *evlist)) == NULL) goto cannot; } if (name && findev(&nxev, name) == NULL || nxev >= Nev) { if ((evp = realloc(evp, (Nev-NEV+1) * sizeof *evp)) == NULL || (evnames = realloc(evnames, (Nev-NEV+1) * sizeof *evnames)) == NULL) goto cannot; evnames[Nev-NEV].number = nxev; evnames[Nev-NEV].name = name; evp[Nev-NEV] = initenv; Nev++; } if (name == NULL && nxev < 0) { flusho(); cannot: errprint("cannot do ev."); if (error) done2(040); else edone(040); return; } evlist[evi++] = ev; e1: if (ev == nxev) return; if ((np = findev(&nxev, name)) == NULL || (op = findev(&ev, NULL)) == NULL) goto cannot; *op = env; env = *np; ev = nxev; if (evname == NULL) if (name) evname = name; else { evname = malloc(20); roff_sprintf(evname, "%d", ev); } }
Offset xxxincoff(Offset p) /* get next blist[] block */ { p++; if (pastend(p)) { /* off the end of this block */ if ((p = blist[bindex(p-1)].nextoff) == -1) { /* and nothing was allocated after it */ ERROR "Bad storage allocation" WARN; done2(-5); } } return(p); }
void grownumtab(void) { ncnt += NDELTA; numtabp = (Numtab *) grow((char *) numtabp, ncnt, sizeof(Numtab)); if (numtabp == NULL) { ERROR "Too many number registers (%d)", ncnt WARN; done2(04); } else { memset((char *)(numtabp) + (ncnt - NDELTA) * sizeof(Numtab), 0, NDELTA * sizeof(Numtab)); nrehash(); } }
void growcontab(void) { nm += MDELTA; contabp = (Contab *) grow((char *) contabp , nm, sizeof(Contab)); if (contabp == NULL) { ERROR "Too many (%d) string/macro names", nm WARN; done2(02); } else { memset((char *)(contabp) + (nm - MDELTA) * sizeof(Contab), 0, MDELTA * sizeof(Contab)); mrehash(); } }
Offset finds(int mn) { int i; Tchar j = IMP; Offset savip; oldmn = findmn(mn); newmn = 0; apptr = 0; if (app && oldmn >= 0 && contabp[oldmn].mx) { savip = ip; ip = contabp[oldmn].emx; oldmn = -1; apptr = ip; if (!diflg) ip = incoff(ip); nextb = ip; ip = savip; } else { for (i = freeslot; i < nm; i++) { if (contabp[i].rq == 0) break; } if (i == nm) growcontab(); freeslot = i + 1; if ((nextb = alloc()) == -1) { app = 0; if (macerr++ > 1) done2(02); if (nextb == 0) ERROR "Not enough space for string/macro names" WARN; edone(04); return(offset = 0); } contabp[i].mx = nextb; if (!diflg) { newmn = i; if (oldmn == -1) contabp[i].rq = -1; } else { contabp[i].rq = mn; maddhash(&contabp[i]); } } app = 0; return(offset = nextb); }
void casedi(void) { int i, j, *k; lgf++; if (skip() || (i = getrq()) == 0) { if (dip != d) { FINDDIV(savslot); wbf((Tchar)0); } if (dilev > 0) { numtabp[DN].val = dip->dnl; numtabp[DL].val = dip->maxl; FINDDIV(j); if ((contabp[j].divsiz = (Divsiz *) malloc(sizeof(Divsiz))) == NULL) { ERROR "Cannot alloc diversion size" WARN; done2(1); } else { contabp[j].divsiz->dix = numtabp[DN].val; contabp[j].divsiz->diy = numtabp[DL].val; } dip = &d[--dilev]; offset = dip->op; } goto rtn; } if (++dilev == NDI) { --dilev; ERROR "Diversions nested too deep" WARN; edone(02); } if (dip != d) { FINDDIV(j); savslot = j; wbf((Tchar)0); } diflg++; dip = &d[dilev]; dip->op = finds(i); dip->curd = i; clrmn(oldmn); k = (int *) & dip->dnl; for (j = 0; j < 10; j++) k[j] = 0; /*not op and curd*/ rtn: app = 0; diflg = 0; }
void blockinit(void) { blist = (Blockp *) calloc(NBLIST, sizeof(Blockp)); if (blist == NULL) { ERROR "not enough room for %d blocks", NBLIST WARN; done2(1); } nblist = NBLIST; blist[0].nextoff = blist[1].nextoff = -1; blist[0].bp = (Tchar *) calloc(BLK, sizeof(Tchar)); blist[1].bp = (Tchar *) calloc(BLK, sizeof(Tchar)); /* -1 prevents blist[0] from being used; temporary fix */ /* for a design botch: offset==0 is overloaded. */ /* blist[1] reserved for .rd indicator -- also unused. */ /* but someone unwittingly looks at these, so allocate something */ bfree = 2; }
void done1(int x) { error |= x; if (numtab[NL].val) { trap = 0; eject((struct s *)0); longjmp(sjbuf, 1); } if (nofeed) { ptlead(); flusho(); done3(0); } else { pttrailer(); done2(0); } }
/* show a main menu with common options when the user presses esc */ void vulture_show_mainmenu() { int winid, n; anything any; menu_item *selected; winid = vulture_create_nhwindow(NHW_MENU); vulture_start_menu(winid); any.a_int = 1; vulture_add_menu(winid, NO_GLYPH, &any, 'h', 0, ATR_BOLD, "Help", MENU_UNSELECTED); any.a_int = 2; vulture_add_menu(winid, NO_GLYPH, &any, 'O', 0, ATR_BOLD, "Options", MENU_UNSELECTED); any.a_int = 3; vulture_add_menu(winid, NO_GLYPH, &any, 'I', 0, ATR_BOLD, "Interface options", MENU_UNSELECTED); any.a_int = 4; vulture_add_menu(winid, NO_GLYPH, &any, 'S', 0, ATR_BOLD, "Save & Quit", MENU_UNSELECTED); any.a_int = 5; vulture_add_menu(winid, NO_GLYPH, &any, 'Q', 0, ATR_BOLD, "Quit", MENU_UNSELECTED); vulture_end_menu(winid, "Main menu"); n = vulture_select_menu(winid, PICK_ONE, &selected); vulture_destroy_nhwindow(winid); if (n < 1) return; switch(selected[0].item.a_int) { case 1: dohelp(); break; case 2: doset(); break; case 3: vulture_iface_opts(); break; case 4: dosave(); break; case 5: done2(); break; } }
void wbf(Tchar i) /* store i into offset, get ready for next one */ { int j, off; if (!offset) return; j = bindex(offset); if (i == 0) contabp[savslot].emx = offset; off = boffset(offset); blist[j].bp[off++] = i; offset++; if (pastend(offset)) { /* off the end of this block */ if (blist[j].nextoff == -1) { if ((nextb = alloc()) == -1) { ERROR "Out of temp file space" WARN; done2(01); } blist[j].nextoff = nextb; } offset = blist[j].nextoff; } }
LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PNHMainWindow data; data = (PNHMainWindow) GetWindowLong(hWnd, GWL_USERDATA); wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // process the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(GetNHApp()->hApp, (LPCTSTR) IDD_ABOUTBOX, hWnd, (DLGPROC) About); break; case IDM_EXIT: done2(); break; case IDM_SAVE: dosave(); break; case IDM_MAP_TILES: case IDM_MAP_ASCII4X6: case IDM_MAP_ASCII6X8: case IDM_MAP_ASCII8X8: case IDM_MAP_ASCII16X8: case IDM_MAP_ASCII7X12: case IDM_MAP_ASCII8X12: case IDM_MAP_ASCII12X16: case IDM_MAP_ASCII16X12: case IDM_MAP_ASCII10X18: mswin_select_map_mode(menuid2mapmode(wmId)); break; case IDM_MAP_FIT_TO_SCREEN: if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) { mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode) ? data->mapAcsiiModeSave : MAP_MODE_TILES); } else { mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode) ? MAP_MODE_ASCII_FIT_TO_SCREEN : MAP_MODE_TILES_FIT_TO_SCREEN); } break; case IDM_VIEW_KEYPAD: GetNHApp()->bCmdPad = !GetNHApp()->bCmdPad; CheckMenuItem( _get_main_menu(ID_VIEW), IDM_VIEW_KEYPAD, MF_BYCOMMAND | (GetNHApp()->bCmdPad ? MF_CHECKED : MF_UNCHECKED)); mswin_layout_main_window(GetNHApp()->hCmdWnd); break; case IDM_VIEW_OPTIONS: doset(); break; case IDM_DIRECT_COMMAND: /* SmartPhone: display dialog to type in arbitary command text */ mswin_direct_command(); break; case IDM_HELP_LONG: display_file(HELP, TRUE); break; case IDM_HELP_COMMANDS: display_file(SHELP, TRUE); break; case IDM_HELP_HISTORY: (void) dohistory(); break; case IDM_HELP_INFO_CHAR: (void) dowhatis(); break; case IDM_HELP_INFO_KEY: (void) dowhatdoes(); break; case IDM_HELP_OPTIONS: option_help(); break; case IDM_HELP_OPTIONS_LONG: display_file(OPTIONFILE, TRUE); break; case IDM_HELP_EXTCMD: (void) doextlist(); break; case IDM_HELP_LICENSE: display_file(LICENSE, TRUE); break; case IDM_HELP_MENU: dohelp(); break; default: return 1; } return 0; }
/** * See QMessageBox for details. */ QIMessageBox::QIMessageBox (const QString &aCaption, const QString &aText, Icon aIcon, int aButton0, int aButton1, int aButton2, QWidget *aParent, const char *aName, bool aModal) : QIDialog (aParent) , mText (aText) , mDetailsIndex (-1) , mWasDone (false) , mWasPolished (false) { #ifdef Q_WS_MAC /* No sheets in another mode than normal for now. Firstly it looks ugly and * secondly in some cases it is broken. */ if (vboxGlobal().isSheetWindowsAllowed(aParent)) setWindowFlags(Qt::Sheet); #endif /* Q_WS_MAC */ setWindowTitle (aCaption); /* Necessary to later find some of the message boxes */ setObjectName (aName); setModal (aModal); mButton0 = aButton0; mButton1 = aButton1; mButton2 = aButton2; QVBoxLayout *layout = new QVBoxLayout (this); #ifdef Q_WS_MAC layout->setContentsMargins (40, 11, 40, 11); #else /* !Q_WS_MAC */ VBoxGlobal::setLayoutMargin (layout, 11); #endif /* !Q_WS_MAC */ layout->setSpacing (10); layout->setSizeConstraint (QLayout::SetMinimumSize); QWidget *main = new QWidget(); QHBoxLayout *hLayout = new QHBoxLayout (main); VBoxGlobal::setLayoutMargin (hLayout, 0); hLayout->setSpacing (10); layout->addWidget (main); mIconLabel = new QLabel(); mIconLabel->setPixmap (standardPixmap (aIcon)); mIconLabel->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Minimum); mIconLabel->setAlignment (Qt::AlignHCenter | Qt::AlignTop); hLayout->addWidget (mIconLabel); QVBoxLayout* messageVBoxLayout = new QVBoxLayout(); VBoxGlobal::setLayoutMargin (messageVBoxLayout, 0); messageVBoxLayout->setSpacing (10); hLayout->addLayout (messageVBoxLayout); mTextLabel = new QILabel (aText); mTextLabel->setAlignment (Qt::AlignLeft | Qt::AlignTop); mTextLabel->setWordWrap (true); QSizePolicy sp (QSizePolicy::Minimum, QSizePolicy::Minimum); sp.setHeightForWidth (true); mTextLabel->setSizePolicy (sp); messageVBoxLayout->addWidget (mTextLabel); mFlagCB_Main = new QCheckBox(); mFlagCB_Main->hide(); messageVBoxLayout->addWidget (mFlagCB_Main); mDetailsVBox = new QWidget(); layout->addWidget (mDetailsVBox); QVBoxLayout* detailsVBoxLayout = new QVBoxLayout (mDetailsVBox); VBoxGlobal::setLayoutMargin (detailsVBoxLayout, 0); detailsVBoxLayout->setSpacing (10); mDetailsText = new QTextEdit(); { /* Calculate the minimum size dynamically, approx. * for 40 chars, 4 lines & 2 <table> margins */ QFontMetrics fm = mDetailsText->fontMetrics(); mDetailsText->setMinimumSize (fm.width ('m') * 40, fm.lineSpacing() * 4 + 4 * 2); } mDetailsText->setReadOnly (true); mDetailsText->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); mDetailsSplitter = new QIArrowSplitter (mDetailsText); connect (mDetailsSplitter, SIGNAL (showBackDetails()), this, SLOT (detailsBack())); connect (mDetailsSplitter, SIGNAL (showNextDetails()), this, SLOT (detailsNext())); detailsVBoxLayout->addWidget (mDetailsSplitter); mFlagCB_Details = new QCheckBox(); mFlagCB_Details->hide(); detailsVBoxLayout->addWidget (mFlagCB_Details); mSpacer = new QSpacerItem (0, 0); layout->addItem (mSpacer); mButtonBox = new QIDialogButtonBox; mButtonBox->setCenterButtons (true); layout->addWidget (mButtonBox); mButtonEsc = 0; mButton0PB = createButton (aButton0); if (mButton0PB) connect (mButton0PB, SIGNAL (clicked()), SLOT (done0())); mButton1PB = createButton (aButton1); if (mButton1PB) connect (mButton1PB, SIGNAL (clicked()), SLOT (done1())); mButton2PB = createButton (aButton2); if (mButton2PB) connect (mButton2PB, SIGNAL (clicked()), SLOT (done2())); /* If this is an error message add an "Copy to clipboard" button for easier * bug reports. */ if (aIcon == QIMessageBox::Critical) { QPushButton *pCopyButton = createButton(Copy); pCopyButton->setToolTip(tr("Copy all errors to the clipboard")); connect(pCopyButton, SIGNAL(clicked()), SLOT(copy())); } /* this call is a must -- it initializes mFlagCB and mSpacer */ setDetailsShown (false); }
void newline(int a) { int i, j, nlss; int opn; nlss = 0; if (a) goto nl1; if (dip != d) { j = lss; pchar1((Tchar)FLSS); if (flss) lss = flss; i = lss + dip->blss; dip->dnl += i; pchar1((Tchar)i); pchar1((Tchar)'\n'); lss = j; dip->blss = flss = 0; if (dip->alss) { pchar1((Tchar)FLSS); pchar1((Tchar)dip->alss); pchar1((Tchar)'\n'); dip->dnl += dip->alss; dip->alss = 0; } if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap && dip->dimac) if (control(dip->dimac, 0)) { trap++; dip->ditf++; } return; } j = lss; if (flss) lss = flss; nlss = dip->alss + dip->blss + lss; numtabp[NL].val += nlss; if (TROFF && ascii) { dip->alss = dip->blss = 0; } pchar1((Tchar)'\n'); flss = 0; lss = j; if (numtabp[NL].val < pl) goto nl2; nl1: ejf = dip->hnl = numtabp[NL].val = 0; ejl = frame; if (donef) { if ((!nc && !wch) || ndone) done1(0); ndone++; donef = 0; if (frame == stk) nflush++; } opn = numtabp[PN].val; numtabp[PN].val++; if (npnflg) { numtabp[PN].val = npn; npn = npnflg = 0; } nlpn: if (numtabp[PN].val == pfrom) { print++; pfrom = -1; } else if (opn == pto) { print = 0; opn = -1; chkpn(); goto nlpn; } if (print) ptpage(numtabp[PN].val); /* supposedly in a clean state so can pause */ if (stop && print) { dpn++; if (dpn >= stop) { dpn = 0; ptpause(); } } nl2: trap = 0; if (numtabp[NL].val == 0) { if ((j = findn(0)) != NTRAP) trap = control(mlist[j], 0); } else if ((i = findt(numtabp[NL].val - nlss)) <= nlss) { if ((j = findn1(numtabp[NL].val - nlss + i)) == NTRAP) { flusho(); ERROR "Trap botch." WARN; done2(-5); } trap = control(mlist[j], 0); } }