void computer::activate_function(game *g, computer_action action) { switch (action) { case COMPACT_NULL: break; // Why would this be called? case COMPACT_OPEN: g->m.translate(t_door_metal_locked, t_floor); print_line("Doors opened."); break; case COMPACT_RELEASE: g->sound(g->u.posx, g->u.posy, 40, "An alarm sounds!"); g->m.translate(t_reinforced_glass_h, t_floor); g->m.translate(t_reinforced_glass_v, t_floor); print_line("Containment shields opened."); break; case COMPACT_TERMINATE: for (int x = 0; x < SEEX * 3; x++) { for (int y = 0; y < SEEY * 3; y++) { int mondex = g->mon_at(x, y); if (mondex != -1 && ((g->m.ter(x, y - 1) == t_reinforced_glass_h && g->m.ter(x, y + 1) == t_wall_h) || (g->m.ter(x, y + 1) == t_reinforced_glass_h && g->m.ter(x, y - 1) == t_wall_h))) g->kill_mon(mondex); } } print_line("Subjects terminated."); break; case COMPACT_PORTAL: for (int i = 0; i < SEEX * 3; i++) { for (int j = 0; j < SEEY * 3; j++) { int numtowers = 0; for (int xt = i - 2; xt <= i + 2; xt++) { for (int yt = j - 2; yt <= j + 2; yt++) { if (g->m.ter(xt, yt) == t_radio_tower) numtowers++; } } if (numtowers == 4) { if (g->m.tr_at(i, j) == tr_portal) g->m.tr_at(i, j) = tr_null; else g->m.add_trap(i, j, tr_portal); } } } break; case COMPACT_CASCADE: { if (!query_yn("WARNING: Resonance cascade carries severe risk! Continue?")) return; std::vector<point> cascade_points; for (int i = g->u.posx - 10; i <= g->u.posx + 10; i++) { for (int j = g->u.posy - 10; j <= g->u.posy + 10; j++) { if (g->m.ter(i, j) == t_radio_tower) cascade_points.push_back(point(i, j)); } } if (cascade_points.size() == 0) g->resonance_cascade(g->u.posx, g->u.posy); else { point p = cascade_points[rng(0, cascade_points.size() - 1)]; g->resonance_cascade(p.x, p.y); } } break; case COMPACT_RESEARCH: { int lines = 0, notes = 0; std::string log, tmp; int ch; std::ifstream fin; fin.open("data/LAB_NOTES"); if (!fin.is_open()) { debugmsg("Couldn't open ./data/LAB_NOTES for reading"); return; } while (fin.good()) { ch = fin.get(); if (ch == '%') notes++; } while (lines < 10) { fin.clear(); fin.seekg(0, std::ios::beg); fin.clear(); int choice = rng(1, notes); while (choice > 0) { getline(fin, tmp); if (tmp.find_first_of('%') == 0) choice--; } bool get_okay; getline(fin, tmp); do { lines++; if (lines < 15 && tmp.find_first_of('%') != 0) { log.append(tmp); log.append("\n"); } } while(tmp.find_first_of('%') != 0 && getline(fin, tmp)); } print_line(log.c_str()); print_line("Press any key..."); getch(); } break; case COMPACT_MAPS: { int minx = int(g->levx / 2) - 40; int maxx = int(g->levx / 2) + 40; int miny = int(g->levy / 2) - 40; int maxy = int(g->levy / 2) + 40; if (minx < 0) minx = 0; if (maxx >= OMAPX) maxx = OMAPX - 1; if (miny < 0) miny = 0; if (maxy >= OMAPY) maxy = OMAPY - 1; overmap tmp(g, g->cur_om.posx, g->cur_om.posy, 0); for (int i = minx; i <= maxx; i++) { for (int j = miny; j <= maxy; j++) tmp.seen(i, j) = true; } tmp.save(g->u.name, g->cur_om.posx, g->cur_om.posy, 0); print_line("Surface map data downloaded."); } break; case COMPACT_MISS_LAUNCH: { overmap tmp_om(g, g->cur_om.posx, g->cur_om.posy, 0); // Target Acquisition. point target = tmp_om.choose_point(g); if (target.x == -1) { print_line("Launch canceled."); return; } // Figure out where the glass wall is... int wall_spot = 0; for (int i = 0; i < SEEX * 3 && wall_spot == 0; i++) { if (g->m.ter(i, 10) == t_wall_glass_v) wall_spot = i; } // ...and put radioactive to the right of it for (int i = wall_spot + 1; i < SEEX * 2 - 1; i++) { for (int j = 1; j < SEEY * 2 - 1; j++) { if (one_in(3)) g->m.add_field(NULL, i, j, fd_nuke_gas, 3); } } // For each level between here and the surface, remove the missile for (int level = g->cur_om.posz; level < 0; level++) { tmp_om = g->cur_om; g->cur_om = overmap(g, tmp_om.posx, tmp_om.posy, level); map tmpmap(&g->itypes, &g->mapitems, &g->traps); tmpmap.load(g, g->levx, g->levy); tmpmap.translate(t_missile, t_hole); tmpmap.save(&tmp_om, g->turn, g->levx, g->levy); } g->cur_om = tmp_om; for (int x = target.x - 2; x <= target.x + 2; x++) { for (int y = target.y - 2; y <= target.y + 2; y++) g->nuke(x, y); } } break; case COMPACT_MISS_DISARM: // TODO: This! break; } // switch (action) }
void userinit(void) { void *v; Proc *p; Segment *s; Page *pg; p = newproc(); p->pgrp = newpgrp(); p->egrp = smalloc(sizeof(Egrp)); p->egrp->ref = 1; p->fgrp = dupfgrp(nil); p->rgrp = newrgrp(); p->procmode = 0640; kstrdup(&eve, ""); kstrdup(&p->text, "*init*"); kstrdup(&p->user, eve); p->fpstate = FPinit; fpoff(); /* * Kernel Stack * * N.B. make sure there's enough space for syscall to check * for valid args and * 4 bytes for gotolabel's return PC */ p->sched.pc = (ulong)init0; p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Sargs)+BY2WD); /* * User Stack * * N.B. cannot call newpage() with clear=1, because pc kmap * requires up != nil. use tmpmap instead. */ s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); p->seg[SSEG] = s; pg = newpage(0, 0, USTKTOP-BY2PG); v = tmpmap(pg); memset(v, 0, BY2PG); segpage(s, pg); bootargs(v); tmpunmap(v); /* * Text */ s = newseg(SG_TEXT, UTZERO, 1); s->flushme++; p->seg[TSEG] = s; pg = newpage(0, 0, UTZERO); memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); segpage(s, pg); v = tmpmap(pg); memset(v, 0, BY2PG); memmove(v, initcode, sizeof initcode); tmpunmap(v); ready(p); }
KMap* kmap(Page *p) { return (KMap*)tmpmap(p); }