/* Return platform decription */ Byte8 *descPlat(Card16 platformId) { if (platformId < SIZE(platform)) return platform[platformId]; else return unknown; }
struct obj *rnd_treefruit_at(int x, int y) { return mksobj_at(treefruits[rn2(SIZE(treefruits))], level, x, y, TRUE, FALSE); }
bool ParseOptionRMB ( int lineNumber, const char *lineText, sRejectOptionRMB *option ) { FUNCTION_ENTRY ( NULL, "ParseOptionRMB", true ); ASSERT ( lineText != NULL ); ASSERT ( option != NULL ); if ( lineNumber > 0 ) { parseLine = lineNumber; parseText = lineText; } memset ( option, 0, sizeof ( sRejectOptionRMB )); const char *srcText = lineText; while (( *srcText != '\0' ) && ( isspace ( *srcText ))) srcText++; if (( *srcText == '#' ) || ( *srcText == '\0' )) return false; size_t length = strlen ( srcText ); char *buffer = new char [ length + 1 ]; for ( size_t i = 0; i < length; i++ ) { buffer [i] = toupper ( srcText [i] ); if (( buffer [i] == '\r' ) || ( buffer [i] == '\n' )) length = i; } buffer [length] = '\0'; char *start = buffer; char *end = buffer; while (( *end != '\0' ) && ( ! isspace ( *end ))) end++; bool retVal = false; if ( start != end ) { for ( unsigned i = 0; i < SIZE ( ParseTable ); i++ ) { char *src = start; const char *tgt = ParseTable [i].Name; while (( src != end ) && ( *tgt != '\0' )) { if ( *src != *tgt ) { if ( *tgt != '*' ) goto next; if ( ! isdigit ( *src )) goto next; } src++; tgt++; } if (( i + 1 < SIZE ( ParseTable )) && ( strncmp ( buffer, ParseTable [i+1].Name, src - buffer ) == 0 )) { ParseError ( "'%*.*s' is not a unique identifier.", end - buffer, end - buffer, buffer ); goto done; } while ( isspace ( *end )) end++; retVal = ParseTable [i].ParseFunction ( end, ParseTable [i], option ); goto done; next: ; } ParseError ( "Unrecognized effect '%*.*s'.", end - buffer, end - buffer, buffer ); } done: delete [] buffer; return retVal; }
PUBLIC int main(int argc, char *argv[]) { message m; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while (TRUE) { int r; int i; if ((r = sef_receive(ANY, &m)) != OK) printf("sef_receive failed %d.\n", r); who_e = m.m_source; call_type = m.m_type; if(verbose) printf("IPC: get %d from %d\n", call_type, who_e); if (call_type & NOTIFY_MESSAGE) { switch (who_e) { case VM_PROC_NR: /* currently, only semaphore needs such information. */ sem_process_vm_notify(); break; default: printf("IPC: ignoring notify() from %d\n", who_e); break; } continue; } /* dispatch messages */ for (i = 0; i < SIZE(ipc_calls); i++) { /* If any process does an IPC call, * we have to know about it exiting. * Tell VM to watch it for us. */ if(vm_watch_exit(m.m_source) != OK) { printf("IPC: watch failed on %d\n", m.m_source); } if (ipc_calls[i].type == call_type) { int result; result = ipc_calls[i].func(&m); if (ipc_calls[i].reply) break; m.m_type = result; if(verbose && result != OK) printf("IPC: error for %d: %d\n", call_type, result); if ((r = sendnb(who_e, &m)) != OK) printf("IPC send error %d.\n", r); break; } } if (i == SIZE(ipc_calls)) { /* warn and then ignore */ printf("IPC unknown call type: %d from %d.\n", call_type, who_e); } update_refcount_and_destroy(); } /* no way to get here */ return -1; }
static bool _convert(CVECTOR *_object, GB_TYPE type, GB_VALUE *conv) { if (THIS) { if (!COMPLEX(THIS)) { switch (type) { case GB_T_FLOAT: conv->_float.value = gsl_blas_dnrm2(VEC(THIS)); return FALSE; case GB_T_SINGLE: conv->_single.value = gsl_blas_dnrm2(VEC(THIS)); return FALSE; case GB_T_INTEGER: case GB_T_SHORT: case GB_T_BYTE: conv->_integer.value = gsl_blas_dnrm2(VEC(THIS)); return FALSE; case GB_T_LONG: conv->_long.value = gsl_blas_dnrm2(VEC(THIS)); return FALSE; case GB_T_STRING: case GB_T_CSTRING: conv->_string.value.addr = _to_string(THIS, type == GB_T_CSTRING); conv->_string.value.start = 0; conv->_string.value.len = GB.StringLength(conv->_string.value.addr); return FALSE; default: break; } } else { switch (type) { case GB_T_FLOAT: conv->_float.value = gsl_blas_dznrm2(CVEC(THIS)); return FALSE; case GB_T_SINGLE: conv->_single.value = gsl_blas_dznrm2(CVEC(THIS)); return FALSE; case GB_T_INTEGER: case GB_T_SHORT: case GB_T_BYTE: conv->_integer.value = gsl_blas_dznrm2(CVEC(THIS)); return FALSE; case GB_T_LONG: conv->_long.value = gsl_blas_dznrm2(CVEC(THIS)); return FALSE; case GB_T_STRING: case GB_T_CSTRING: conv->_string.value.addr = _to_string(THIS, type == GB_T_CSTRING); conv->_string.value.start = 0; conv->_string.value.len = GB.StringLength(conv->_string.value.addr); return FALSE; default: break; } } // Vector ---> Float[] if ((type == GB.FindClass("Float[]") || type == CLASS_Polynomial) && !COMPLEX(THIS)) { GB_ARRAY a; int i; double *data; GB.Array.New(&a, GB_T_FLOAT, SIZE(THIS)); data = (double *)GB.Array.Get(a, 0); for(i = 0; i < SIZE(THIS); i++) data[i] = gsl_vector_get(VEC(THIS), i); conv->_object.value = a; if (type != CLASS_Polynomial) return FALSE; } // Vector ---> Complex[] else if (type == GB.FindClass("Complex[]") || type == CLASS_Polynomial) { GB_ARRAY a; int i; void **data; CCOMPLEX *c; GB.Array.New(&a, CLASS_Complex, SIZE(THIS)); data = (void **)GB.Array.Get(a, 0); for(i = 0; i < SIZE(THIS); i++) { c = COMPLEX_create(COMPLEX(THIS) ? gsl_vector_complex_get(CVEC(THIS), i) : gsl_complex_rect(gsl_vector_get(VEC(THIS), i), 0)); data[i] = c; GB.Ref(c); } conv->_object.value = a; if (type != CLASS_Polynomial) return FALSE; } else return TRUE; // Vector ---> Polynomial if (type == CLASS_Polynomial) { void *unref = conv->_object.value; GB.Ref(unref); // Will be unref by the next GB.Conv() POLYNOMIAL_convert(FALSE, type, conv); GB.Unref(&unref); // Will be unref by the next GB.Conv() //GB.Conv(conv, type); //GB.UnrefKeep(&conv->_object.value, FALSE); // Will be ref again after the current GB.Conv() return FALSE; } } else if (type >= GB_T_OBJECT) { if (GB.Is(conv->_object.value, CLASS_Array)) { GB_ARRAY array = (GB_ARRAY)conv->_object.value; int size = GB.Array.Count(array); CVECTOR *v; int i; GB_VALUE temp; void *data; GB_TYPE atype = GB.Array.Type(array); // Float[] Integer[] ... ---> Vector if (atype > GB_T_BOOLEAN && atype <= GB_T_FLOAT) { v = VECTOR_create(size, FALSE, FALSE); for (i = 0; i < size; i++) { data = GB.Array.Get(array, i); GB.ReadValue(&temp, data, atype); GB.Conv(&temp, GB_T_FLOAT); gsl_vector_set(VEC(v), i, temp._float.value); } conv->_object.value = v; return FALSE; } // Variant[] ---> Vector else if (atype == GB_T_VARIANT) { CCOMPLEX *c; v = VECTOR_create(size, TRUE, FALSE); for (i = 0; i < size; i++) { GB.ReadValue(&temp, GB.Array.Get(array, i), atype); GB.BorrowValue(&temp); GB.Conv(&temp, CLASS_Complex); c = temp._object.value; if (c) gsl_vector_complex_set(CVEC(v), i, c->number); else gsl_vector_complex_set(CVEC(v), i, COMPLEX_zero); GB.ReleaseValue(&temp); } conv->_object.value = v; return FALSE; } // Complex[] ---> Vector else if (atype == CLASS_Complex) { CCOMPLEX *c; v = VECTOR_create(size, TRUE, FALSE); for (i = 0; i < size; i++) { c = *((CCOMPLEX **)GB.Array.Get(array, i)); if (c) gsl_vector_complex_set(CVEC(v), i, c->number); else gsl_vector_complex_set(CVEC(v), i, COMPLEX_zero); } conv->_object.value = v; return FALSE; } } // Float Integer... ---> Vector else if (type > GB_T_BOOLEAN && type <= GB_T_FLOAT) { CVECTOR *v = VECTOR_create(1, FALSE, FALSE); if (type == GB_T_FLOAT) gsl_vector_set(VEC(v), 0, conv->_float.value); else if (type == GB_T_SINGLE) gsl_vector_set(VEC(v), 0, conv->_single.value); else gsl_vector_set(VEC(v), 0, conv->_integer.value); conv->_object.value = v; return FALSE; } // Complex ---> Vector else if (type == CLASS_Complex) { CCOMPLEX *c = (CCOMPLEX *)conv->_object.value; CVECTOR *v = VECTOR_create(1, TRUE, FALSE); gsl_vector_complex_set(CVEC(v), 0, c->number); conv->_object.value = v; return FALSE; } } return TRUE; }
/* Allocate a block of size size and return a pointer to it. */ void* mm_malloc (size_t size) { size_t reqSize; BlockInfo * ptrFreeBlock = NULL; size_t blockSize; size_t precedingBlockUseTag; BlockInfo * nextBlock = NULL; BlockInfo * newBlock = NULL; // Zero-size requests get NULL. if (size == 0) { return NULL; } // Add one word for the initial size header. // Note that we don't need to boundary tag when the block is used! size += WORD_SIZE; if (size <= MIN_BLOCK_SIZE) { // Make sure we allocate enough space for a blockInfo in case we // free this block (when we free this block, we'll need to use the // next pointer, the prev pointer, and the boundary tag). reqSize = MIN_BLOCK_SIZE; } else { // Round up for correct alignment reqSize = ALIGNMENT * ((size + ALIGNMENT - 1) / ALIGNMENT); } // Implement mm_malloc. You can change or remove any of the above // code. It is included as a suggestion of where to start. // You will want to replace this return statement... /* ptrFreeBlock = searchFreeList(reqSize); if( ptrFreeBlock != NULL) { blockSize = SIZE(ptrFreeBlock->sizeAndTags); nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize); nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED; removeFreeBlock(ptrFreeBlock); ptrFreeBlock->sizeAndTags = ptrFreeBlock->sizeAndTags | TAG_USED; return POINTER_ADD( ptrFreeBlock, WORD_SIZE); } requestMoreSpace(reqSize); ptrFreeBlock = searchFreeList(reqSize); if( ptrFreeBlock != NULL) { blockSize = SIZE(ptrFreeBlock->sizeAndTags); nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize); nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED; removeFreeBlock(ptrFreeBlock); ptrFreeBlock->sizeAndTags = ptrFreeBlock->sizeAndTags | TAG_USED; return POINTER_ADD( ptrFreeBlock, WORD_SIZE); } */ ptrFreeBlock = searchFreeList(reqSize); if( ptrFreeBlock == NULL){ requestMoreSpace(reqSize); ptrFreeBlock = searchFreeList(reqSize); } blockSize = SIZE(ptrFreeBlock->sizeAndTags); if( (blockSize - reqSize) >= MIN_BLOCK_SIZE ){ precedingBlockUseTag = ptrFreeBlock->sizeAndTags & TAG_PRECEDING_USED; ptrFreeBlock->sizeAndTags = reqSize | precedingBlockUseTag | TAG_USED ; removeFreeBlock(ptrFreeBlock); newBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, reqSize); newBlock->sizeAndTags = blockSize - reqSize; newBlock->sizeAndTags = newBlock->sizeAndTags | TAG_PRECEDING_USED; *((size_t*)POINTER_ADD(newBlock, blockSize - reqSize - WORD_SIZE ) ) = newBlock->sizeAndTags; insertFreeBlock(newBlock); }else{ nextBlock = (BlockInfo* )POINTER_ADD(ptrFreeBlock, blockSize); nextBlock->sizeAndTags = nextBlock->sizeAndTags | TAG_PRECEDING_USED; ptrFreeBlock->sizeAndTags = ptrFreeBlock->sizeAndTags | TAG_USED; removeFreeBlock(ptrFreeBlock); } return POINTER_ADD( ptrFreeBlock, WORD_SIZE); }
bool charset_conv::update(const char* in, size_t len, acl::string* out) { #ifdef HAVE_H_ICONV if (in == NULL) logger_fatal("in null"); if (out == NULL) logger_fatal("out null"); if (EQ(m_fromCharset, m_toCharset)) { out->append(in, len); return (true); } if (m_iconv == (iconv_t) -1) { logger_error("m_iconv invalid"); m_errmsg = "m_iconv invalid"; return (false); } // 去掉有些 UTF-8 文档中开始的 UTF-8 引导符 if (*m_pUtf8Pre) { while (len > 0) { if (*m_pUtf8Pre == 0x00) break; else if (*m_pUtf8Pre != *in) { // 必须使 UTF-8 前缀失效 m_pUtf8Pre = &UTF8_HEADER[3]; break; } m_pUtf8Pre++; in++; len--; } } if (len == 0) return (true); if (m_pInBuf == NULL) m_pInBuf = acl_vstring_alloc(len); if (m_pOutBuf == NULL) m_pOutBuf = acl_vstring_alloc(len); else ACL_VSTRING_SPACE(m_pOutBuf, len); // 先将输入数据进行缓冲 if (*m_pUtf8Pre && m_pUtf8Pre - UTF8_HEADER > 0) acl_vstring_memcpy(m_pInBuf, UTF8_HEADER, m_pUtf8Pre - UTF8_HEADER); acl_vstring_memcat(m_pInBuf, in, len); ACL_VSTRING_TERMINATE(m_pInBuf); char *pIn, *pOut; size_t ret, nIn, nOut; while (true) { nIn = LEN(m_pInBuf); if (nIn == 0) break; pIn = STR(m_pInBuf); pOut = STR(m_pOutBuf); nOut = SIZE(m_pOutBuf); #ifdef WIN32 # ifdef USE_WIN_ICONV ret = __iconv(m_iconv, (const char**) &pIn, &nIn, &pOut, &nOut); # else int err; ret = __iconv(m_iconv, (const char**) &pIn, &nIn, &pOut, &nOut, &err); errno = err; # endif // USE_WIN_ICONV #elif defined(ACL_SUNOS5) || defined(ACL_FREEBSD) ret = __iconv(m_iconv, (const char**) &pIn, &nIn, &pOut, &nOut); #else ret = __iconv(m_iconv, &pIn, &nIn, &pOut, &nOut); #endif if (ret != (size_t) -1) { if ((ret = SIZE(m_pOutBuf) - nOut) > 0) out->append(STR(m_pOutBuf), ret); else // xxx out->append(in, len); ACL_VSTRING_RESET(m_pInBuf); break; } else if (errno == E2BIG) { if ((ret = SIZE(m_pOutBuf) - nOut) > 0) out->append(STR(m_pOutBuf), ret); if (pIn > STR(m_pInBuf) && nIn < LEN(m_pInBuf)) acl_vstring_memmove(m_pInBuf, pIn, nIn); // 扩大内存空间 ACL_VSTRING_SPACE(m_pOutBuf, SIZE(m_pOutBuf) * 2); continue; } else if (errno == EILSEQ) { char *pNil = NULL; size_t zero = 0; // 重置状态, 似乎也没啥用处 #ifdef WIN32 # ifdef USE_WIN_ICONV __iconv(m_iconv, (const char**) &pNil, &zero, &pNil, &zero); # else __iconv(m_iconv, (const char**) &pNil, &zero, &pNil, &zero, NULL); # endif #elif defined(ACL_SUNOS5) || defined(ACL_FREEBSD) __iconv(m_iconv, (const char**) &pNil, &zero, &pNil, &zero); #else __iconv(m_iconv, &pNil, &zero, &pNil, &zero); #endif // 遇到无效的多字节序列,pIn 指向第一个无效的位置 // 先拷贝已经转换的数据 if ((ret = SIZE(m_pOutBuf) - nOut) > 0) out->append(STR(m_pOutBuf), ret); if (nIn == 0) { ACL_VSTRING_RESET(m_pInBuf); break; } acl_assert(pIn >= STR(m_pInBuf)); // 跳过无效字节 (*out) += (char)(*pIn); // 直接拷贝无效字节 nIn--; pIn++; if (nIn > 0) acl_vstring_memmove(m_pInBuf, pIn, nIn); else ACL_VSTRING_RESET(m_pInBuf); } else if (errno == EINVAL) { char *pNil = NULL; size_t zero = 0; // 重置状态, 似乎也没啥用处 #ifdef WIN32 # ifdef USE_WIN_ICONV __iconv(m_iconv, (const char**) &pNil, &zero, &pNil, &zero); # else __iconv(m_iconv, (const char**) &pNil, &zero, &pNil, &zero, NULL); # endif // USE_WIN_ICONV #elif defined(ACL_SUNOS5) || defined(ACL_FREEBSD) __iconv(m_iconv, (const char**) &pNil, &zero, &pNil, &zero); #else __iconv(m_iconv, &pNil, &zero, &pNil, &zero); #endif // 输入的多字节序列不完整,pIn 指向该不完整的位置 // 先拷贝已经转换的数据 if ((ret = SIZE(m_pOutBuf) - nOut) > 0) out->append(STR(m_pOutBuf), ret); // 移动数据,将未转换的数据移至缓冲区起始位置 if (nIn > 0) acl_vstring_memmove(m_pInBuf, pIn, nIn); else ACL_VSTRING_RESET(m_pInBuf); break; } else if (LEN(m_pInBuf) > 0) { // 如果遇到了无效的字符集,根据设置的标志位 // 决定是否直接拷贝 if (m_addInvalid) { out->append(STR(m_pInBuf), LEN(m_pInBuf)); ACL_VSTRING_RESET(m_pInBuf); } break; } else break; } return (true); #else (void) in; (void) len; (void) out; logger_error("no iconv lib"); m_errmsg = "no iconv lib"; return (false); #endif }
/* $e <- a$ */ static void gf3m_assign(element_t e, element_t a) { memcpy(e->data, a->data, SIZE(a)); }
boolean validrole(int rolenum) { return rolenum >= 0 && rolenum < SIZE(roles)-1; }
/* $a <- 0$ */ static void gf3m_zero(element_t a) { memset(a->data, 0, SIZE(a)); }
static void gf3m_init(element_t e) { e->data = pbc_malloc(SIZE(e)); gf3m_zero(e); }
int main(int argc, char* argv[]) { enum { single, replicated, missing } mode; int logTargets; const char* user; char buf[4096]; bool deleteDB; bool firstRun; firstRun = true; mode = missing; if (argc == 1) { fprintf(stderr, "You did not specify a config file!\n"); fprintf(stderr, "Starting in single mode with defaults...\n"); fprintf(stderr, "Using database.dir = '%s'\n", DATABASE_CONFIG_DIR); mode = single; } else if (argc == 2) { if (!Config::Init(argv[1])) STOP_FAIL("Cannot open config file", 1); } else { fprintf(stderr, "usage: %s <config-file>\n", argv[0]); STOP_FAIL("invalid arguments", 1); } if (strcmp("single", Config::GetValue("mode", "")) == 0) mode = single; else if (strcmp("replicated", Config::GetValue("mode", "")) == 0) mode = replicated; else if (mode == missing) { fprintf(stderr, "specify mode = single or mode = replicated\n"); STOP_FAIL("invalid configuration file", 1); } logTargets = 0; if (Config::GetListNum("log.targets") == 0) logTargets = LOG_TARGET_STDOUT; for (int i = 0; i < Config::GetListNum("log.targets"); i++) { if (strcmp(Config::GetListValue("log.targets", i, ""), "file") == 0) { logTargets |= LOG_TARGET_FILE; Log_SetOutputFile(Config::GetValue("log.file", NULL), Config::GetBoolValue("log.truncate", false)); } if (strcmp(Config::GetListValue("log.targets", i, NULL), "stdout") == 0) logTargets |= LOG_TARGET_STDOUT; if (strcmp(Config::GetListValue("log.targets", i, NULL), "stderr") == 0) logTargets |= LOG_TARGET_STDERR; } Log_SetTarget(logTargets); Log_SetTrace(Config::GetBoolValue("log.trace", false)); Log_SetTimestamping(Config::GetBoolValue("log.timestamping", false)); Log_Message(VERSION_FMT_STRING " started"); run: { if (!IOProcessor::Init(Config::GetIntValue("io.maxfd", 1024))) STOP_FAIL("Cannot initalize IOProcessor!", 1); // after io is initialized, drop root rights user = Config::GetValue("daemon.user", NULL); if (!ChangeUser(user)) STOP_FAIL(rprintf("Cannot setuid to %s", user), 1); DatabaseConfig dbConfig; dbConfig.dir = Config::GetValue("database.dir", DATABASE_CONFIG_DIR); dbConfig.pageSize = Config::GetIntValue("database.pageSize", DATABASE_CONFIG_PAGE_SIZE); dbConfig.cacheSize = Config::GetIntValue("database.cacheSize", DATABASE_CONFIG_CACHE_SIZE); dbConfig.logBufferSize = Config::GetIntValue("database.logBufferSize", DATABASE_CONFIG_LOG_BUFFER_SIZE); dbConfig.checkpointTimeout = Config::GetIntValue("database.checkpointTimeout", DATABASE_CONFIG_CHECKPOINT_TIMEOUT); dbConfig.verbose = Config::GetBoolValue("database.verbose", DATABASE_CONFIG_VERBOSE); dbConfig.directDB = Config::GetBoolValue("database.directDB", DATABASE_CONFIG_DIRECT_DB); dbConfig.txnNoSync = Config::GetBoolValue("database.txnNoSync", DATABASE_CONFIG_TXN_NOSYNC); dbConfig.txnWriteNoSync = Config::GetBoolValue("database.txnWriteNoSync", DATABASE_CONFIG_TXN_WRITE_NOSYNC); if (Config::GetBoolValue("database.warmCache", true) && firstRun) WarmCache((char*)dbConfig.dir, dbConfig.cacheSize); if (firstRun) Log_Message("Opening database..."); if (!database.Init(dbConfig)) STOP_FAIL("Cannot initialize database!", 1); if (firstRun) Log_Message("Database opened"); dbWriter.Init(1); dbReader.Init(Config::GetIntValue("database.numReaders", 20)); if (!RCONF->Init()) STOP_FAIL("Cannot initialize paxos!", 1); KeyspaceDB* kdb; if (mode == replicated) { RLOG->Init(Config::GetBoolValue("paxos.useSoftClock", true)); kdb = new ReplicatedKeyspaceDB; } else { kdb = new SingleKeyspaceDB; } kdb->Init(); HttpServer protoHttp; HttpKeyspaceHandler httpKeyspaceHandler(kdb); int httpPort = Config::GetIntValue("http.port", 8080); if (httpPort) { protoHttp.Init(httpPort); protoHttp.RegisterHandler(&httpKeyspaceHandler); } KeyspaceServer protoKeyspace; protoKeyspace.Init(kdb, Config::GetIntValue("keyspace.port", 7080)); EventLoop::Init(); EventLoop::Run(); EventLoop::Shutdown(); if (mode == replicated) deleteDB = ((ReplicatedKeyspaceDB*)kdb)->DeleteDB(); else deleteDB = false; protoKeyspace.Shutdown(); protoHttp.Shutdown(); kdb->Shutdown(); delete kdb; dbReader.Shutdown(); dbWriter.Shutdown(); RLOG->Shutdown(); database.Shutdown(); IOProcessor::Shutdown(); if (mode == replicated && deleteDB) { // snprintf(buf, SIZE(buf), "%s/__*", dbConfig.dir); // DeleteWC(buf); snprintf(buf, SIZE(buf), "%s/log*", dbConfig.dir); DeleteWC(buf); snprintf(buf, SIZE(buf), "%s/keyspace", dbConfig.dir); DeleteWC(buf); #ifdef _WIN32 MSleep(3000); // otherwise Windows won't let use reuse the same ports #endif firstRun = false; goto run; } } Log_Message("Keyspace shutting down."); Config::Shutdown(); Log_Shutdown(); }
void WriteChimeHitX(FILE *f, const ChimeHit2 &Hit) { if (f == 0) return; if (Hit.Div <= 0.0) return; const string &Q3 = Hit.Q3; const string &A3 = Hit.A3; const string &B3 = Hit.B3; const byte *Q3Seq = (const byte *) Q3.c_str(); const byte *A3Seq = (const byte *) A3.c_str(); const byte *B3Seq = (const byte *) B3.c_str(); // Aligned unsigned ColCount = SIZE(Q3); asserta(SIZE(A3) == ColCount && SIZE(B3) == ColCount); unsigned LQ = GetUngappedLength(Q3Seq, ColCount); unsigned LA = GetUngappedLength(A3Seq, ColCount); unsigned LB = GetUngappedLength(B3Seq, ColCount); fprintf(f, "\n"); fprintf(f, "------------------------------------------------------------------------\n"); fprintf(f, "Query (%5u nt) %s\n", LQ, Hit.QLabel.c_str()); fprintf(f, "ParentA (%5u nt) %s\n", LA, Hit.ALabel.c_str()); fprintf(f, "ParentB (%5u nt) %s\n", LB, Hit.BLabel.c_str()); // Strip terminal gaps in query unsigned FromCol = UINT_MAX; unsigned ToCol = UINT_MAX; for (unsigned Col = 0; Col < ColCount; ++Col) { if (!isgap(Q3Seq[Col])) { if (FromCol == UINT_MAX) FromCol = Col; ToCol = Col; } } unsigned QPos = 0; unsigned APos = 0; unsigned BPos = 0; for (unsigned Col = 0; Col < FromCol; ++Col) { if (!isgap(A3Seq[Col])) ++APos; if (!isgap(B3Seq[Col])) ++BPos; } unsigned Range = ToCol - FromCol + 1; unsigned RowCount = (Range + 79)/80; unsigned RowFromCol = FromCol; for (unsigned RowIndex = 0; RowIndex < RowCount; ++RowIndex) { fprintf(f, "\n"); unsigned RowToCol = RowFromCol + 79; if (RowToCol > ToCol) RowToCol = ToCol; // A row fprintf(f, "A %5u ", APos + 1); for (unsigned Col = RowFromCol; Col <= RowToCol; ++Col) { char q = Q3Seq[Col]; char a = A3Seq[Col]; if (a != q) a = tolower(a); fprintf(f, "%c", a); if (!isgap(a)) ++APos; } fprintf(f, " %u\n", APos); // Q row fprintf(f, "Q %5u ", QPos + 1); for (unsigned Col = RowFromCol; Col <= RowToCol; ++Col) { char q = Q3Seq[Col]; fprintf(f, "%c", q); if (!isgap(q)) ++QPos; } fprintf(f, " %u\n", QPos); // B row fprintf(f, "B %5u ", BPos + 1); for (unsigned Col = RowFromCol; Col <= RowToCol; ++Col) { char q = Q3Seq[Col]; char b = B3Seq[Col]; if (b != q) b = tolower(b); fprintf(f, "%c", b); if (!isgap(b)) ++BPos; } fprintf(f, " %u\n", BPos); // Diffs fprintf(f, "Diffs "); for (unsigned Col = RowFromCol; Col <= RowToCol; ++Col) { char q = Q3Seq[Col]; char a = A3Seq[Col]; char b = B3Seq[Col]; char c = ' '; if (isgap(q) || isgap(a) || isgap(b)) c = ' '; else if (Col < Hit.ColXLo) { if (q == a && q == b) c = ' '; else if (q == a && q != b) c = 'A'; else if (q == b && q != a) c = 'b'; else if (a == b && q != a) c = 'N'; else c = '?'; } else if (Col > Hit.ColXHi) { if (q == a && q == b) c = ' '; else if (q == b && q != a) c = 'B'; else if (q == a && q != b) c = 'a'; else if (a == b && q != a) c = 'N'; else c = '?'; } fprintf(f, "%c", c); } fprintf(f, "\n"); // SNPs fprintf(f, "Votes "); for (unsigned Col = RowFromCol; Col <= RowToCol; ++Col) { char q = Q3Seq[Col]; char a = A3Seq[Col]; char b = B3Seq[Col]; bool PrevGap = Col > 0 && (isgap(Q3Seq[Col-1]) || isgap(A3Seq[Col-1]) || isgap(B3Seq[Col-1])); bool NextGap = Col+1 < ColCount && (isgap(Q3Seq[Col+1]) || isgap(A3Seq[Col+1]) || isgap(B3Seq[Col+1])); char c = ' '; if (isgap(q) || isgap(a) || isgap(b) || PrevGap || NextGap) c = ' '; else if (Col < Hit.ColXLo) { if (q == a && q == b) c = ' '; else if (q == a && q != b) c = '+'; else if (q == b && q != a) c = '!'; else c = '0'; } else if (Col > Hit.ColXHi) { if (q == a && q == b) c = ' '; else if (q == b && q != a) c = '+'; else if (q == a && q != b) c = '!'; else c = '0'; } fprintf(f, "%c", c); } fprintf(f, "\n"); // LR row fprintf(f, "Model "); for (unsigned Col = RowFromCol; Col <= RowToCol; ++Col) { if (Col < Hit.ColXLo) fprintf(f, "A"); else if (Col >= Hit.ColXLo && Col <= Hit.ColXHi) fprintf(f, "x"); else fprintf(f, "B"); } fprintf(f, "\n"); RowFromCol += 80; } fprintf(f, "\n"); double PctIdBestP = max(Hit.PctIdQA, Hit.PctIdQB); double Div = (Hit.PctIdQM - PctIdBestP)*100.0/PctIdBestP; unsigned LTot = Hit.CS_LY + Hit.CS_LN + Hit.CS_LA; unsigned RTot = Hit.CS_RY + Hit.CS_RN + Hit.CS_RA; double PctL = Pct(Hit.CS_LY, LTot); double PctR = Pct(Hit.CS_RY, RTot); fprintf(f, "Ids. QA %.1f%%, QB %.1f%%, AB %.1f%%, QModel %.1f%%, Div. %+.1f%%\n", Hit.PctIdQA, Hit.PctIdQB, Hit.PctIdAB, Hit.PctIdQM, Div); fprintf(f, "Diffs Left %u: N %u, A %u, Y %u (%.1f%%); Right %u: N %u, A %u, Y %u (%.1f%%), Score %.4f\n", LTot, Hit.CS_LN, Hit.CS_LA, Hit.CS_LY, PctL, RTot, Hit.CS_RN, Hit.CS_RA, Hit.CS_RY, PctR, Hit.Score); }
/* Lookup Microsoft LCID */ static Byte8 *MSLangLookup(Card16 LCID) { MSLangEntry *entry = (MSLangEntry *)bsearch(&LCID, MSLanguage, SIZE(MSLanguage), sizeof(MSLangEntry), matchLCIDs); return entry == NULL ? unknown : entry->desc; }
void wipeout_text(char *engr, int cnt, unsigned seed) { /* for semi-controlled randomization */ char *s; int i, j, nxt, use_rubout, lth = (int)strlen(engr); if (lth && cnt > 0) { while (cnt--) { /* pick next character */ if (!seed) { /* random */ nxt = rn2(lth); use_rubout = rn2(4); } else { /* predictable; caller can reproduce the same sequence by supplying the same arguments later, or a pseudo-random sequence by varying any of them */ nxt = seed % lth; seed *= 31; seed %= 255; /* previously BUFSZ-1 */ if (!seed) seed++; use_rubout = seed & 3; } s = &engr[nxt]; if (*s == ' ') continue; /* rub out unreadable & small punctuation marks */ if (strchr("?.,'`-|_", *s)) { *s = ' '; continue; } if (!use_rubout) i = SIZE(rubouts); else for (i = 0; i < SIZE(rubouts); i++) if (*s == rubouts[i].wipefrom) { /* * Pick one of the substitutes at random. */ if (!seed) j = rn2(strlen(rubouts[i].wipeto)); else { seed *= 31; seed %= 255; j = seed % (strlen(rubouts[i].wipeto)); if (!seed) seed++; } *s = rubouts[i].wipeto[j]; break; } /* didn't pick rubout; use '?' for unreadable character */ if (i == SIZE(rubouts)) *s = '?'; } } /* trim trailing spaces */ while (lth && engr[lth - 1] == ' ') engr[--lth] = 0; }
int randrole(void) { return rn2(SIZE(roles)-1); }
/* Coalesce 'oldBlock' with any preceeding or following free blocks. */ static void coalesceFreeBlock(BlockInfo* oldBlock) { BlockInfo *blockCursor; BlockInfo *newBlock; BlockInfo *freeBlock; // size of old block size_t oldSize = SIZE(oldBlock->sizeAndTags); // running sum to be size of final coalesced block size_t newSize = oldSize; // Coalesce with any preceding free block blockCursor = oldBlock; while ((blockCursor->sizeAndTags & TAG_PRECEDING_USED)==0) { // While the block preceding this one in memory (not the // prev. block in the free list) is free: // Get the size of the previous block from its boundary tag. size_t size = SIZE(*((size_t*)POINTER_SUB(blockCursor, WORD_SIZE))); // Use this size to find the block info for that block. freeBlock = (BlockInfo*)POINTER_SUB(blockCursor, size); // Remove that block from free list. removeFreeBlock(freeBlock); // Count that block's size and update the current block pointer. newSize += size; blockCursor = freeBlock; } newBlock = blockCursor; // Coalesce with any following free block. // Start with the block following this one in memory blockCursor = (BlockInfo*)POINTER_ADD(oldBlock, oldSize); while ((blockCursor->sizeAndTags & TAG_USED)==0) { // While the block is free: size_t size = SIZE(blockCursor->sizeAndTags); // Remove it from the free list. removeFreeBlock(blockCursor); // Count its size and step to the following block. newSize += size; blockCursor = (BlockInfo*)POINTER_ADD(blockCursor, size); } // If the block actually grew, remove the old entry from the free // list and add the new entry. if (newSize != oldSize) { // Remove the original block from the free list removeFreeBlock(oldBlock); // Save the new size in the block info and in the boundary tag // and tag it to show the preceding block is used (otherwise, it // would have become part of this one!). newBlock->sizeAndTags = newSize | TAG_PRECEDING_USED; // The boundary tag of the preceding block is the word immediately // preceding block in memory where we left off advancing blockCursor. *(size_t*)POINTER_SUB(blockCursor, WORD_SIZE) = newSize | TAG_PRECEDING_USED; // Put the new block in the free list. insertFreeBlock(newBlock); } return; }
/* initialize gnome and fir up the main window */ void ghack_init_main_window( int argc, char** argv) { int i; struct timeval tv; uid_t uid, euid; /* It seems that the authors of gnome_score_init() drop group * priveledges. We need group priveledges, so until we change the * way we save games to do things the gnome way(???), this stays * commented out. (after hours of frusteration...) * -Erik */ /* gnome_score_init("gnomehack"); */ gettimeofday(&tv, NULL); srand(tv.tv_usec); uid = getuid(); euid = geteuid(); if (uid != euid) setuid(uid); hide_privileges(TRUE); /* XXX gnome_init must print nethack options for --help, but does not */ gnome_init ("nethack", VERSION_STRING, argc, argv); hide_privileges(FALSE); parse_args (argc, argv); /* Initialize the i18n stuff (not that gnomehack supperts it yet...) */ #if 0 textdomain (PACKAGE); #endif gdk_imlib_init(); /* Main window */ mainWindow = gnome_app_new((char *) "nethack", (char *) N_("Nethack for Gnome")); gtk_widget_realize(mainWindow); if (restarted) { gtk_widget_set_uposition (mainWindow, os_x, os_y); gtk_widget_set_usize (mainWindow, os_w, os_h); } gtk_window_set_default_size( GTK_WINDOW(mainWindow), 800, 600); gtk_window_set_policy(GTK_WINDOW(mainWindow), FALSE, TRUE, TRUE); gnome_app_create_menus(GNOME_APP(mainWindow), mainmenu); gtk_signal_connect(GTK_OBJECT(mainWindow), "key_press_event", GTK_SIGNAL_FUNC(ghack_main_window_key_press), NULL); gtk_signal_connect(GTK_OBJECT(mainWindow), "delete_event", GTK_SIGNAL_FUNC(ghack_quit_game_cb), NULL); /* Put some stuff into our main window */ vBoxMain = gtk_vbox_new (FALSE, 0); hBoxFirstRow = gtk_hbox_new (FALSE, 0); /* pack Boxes into other boxes to produce the right structure */ gtk_box_pack_start (GTK_BOX (vBoxMain), hBoxFirstRow, FALSE, TRUE, 0); /* pack vBoxMain which contains all our widgets into the main window. */ gnome_app_set_contents(GNOME_APP(mainWindow), vBoxMain); /* DONT show the main window yet, due to a Gtk bug that causes it * to not refresh the window when adding widgets after the window * has already been shown */ if (uid != euid) setuid(euid); for(i = 0; i < SIZE(ghack_chain); i++) ghack_chain[i].handler = signal(ghack_chain[i].signum, ghack_sig_handler); }
void io_wait_dowork (struct context *c, const unsigned int flags) { unsigned int socket = 0; unsigned int tuntap = 0; struct event_set_return esr[4]; /* These shifts all depend on EVENT_READ and EVENT_WRITE */ static int socket_shift = 0; /* depends on SOCKET_READ and SOCKET_WRITE */ static int tun_shift = 2; /* depends on TUN_READ and TUN_WRITE */ static int err_shift = 4; /* depends on ES_ERROR */ #ifdef ENABLE_MANAGEMENT static int management_shift = 6; /* depends on MANAGEMENT_READ and MANAGEMENT_WRITE */ #endif /* * Decide what kind of events we want to wait for. */ event_reset (c->c2.event_set); /* * On win32 we use the keyboard or an event object as a source * of asynchronous signals. */ if (flags & IOW_WAIT_SIGNAL) wait_signal (c->c2.event_set, (void*)&err_shift); /* * If outgoing data (for TCP/UDP port) pending, wait for ready-to-send * status from TCP/UDP port. Otherwise, wait for incoming data on * TUN/TAP device. */ if (flags & IOW_TO_LINK) { if (flags & IOW_SHAPER) { /* * If sending this packet would put us over our traffic shaping * quota, don't send -- instead compute the delay we must wait * until it will be OK to send the packet. */ #ifdef HAVE_GETTIMEOFDAY int delay = 0; /* set traffic shaping delay in microseconds */ if (c->options.shaper) delay = max_int (delay, shaper_delay (&c->c2.shaper)); if (delay < 1000) { socket |= EVENT_WRITE; } else { shaper_soonest_event (&c->c2.timeval, delay); } #else /* HAVE_GETTIMEOFDAY */ socket |= EVENT_WRITE; #endif /* HAVE_GETTIMEOFDAY */ } else { socket |= EVENT_WRITE; } } else if (!((flags & IOW_FRAG) && TO_LINK_FRAG (c))) { if (flags & IOW_READ_TUN) tuntap |= EVENT_READ; } /* * If outgoing data (for TUN/TAP device) pending, wait for ready-to-send status * from device. Otherwise, wait for incoming data on TCP/UDP port. */ if (flags & IOW_TO_TUN) { tuntap |= EVENT_WRITE; } else { if (flags & IOW_READ_LINK) socket |= EVENT_READ; } /* * outgoing bcast buffer waiting to be sent? */ if (flags & IOW_MBUF) socket |= EVENT_WRITE; /* * Force wait on TUN input, even if also waiting on TCP/UDP output */ if (flags & IOW_READ_TUN_FORCE) tuntap |= EVENT_READ; /* * Configure event wait based on socket, tuntap flags. */ socket_set (c->c2.link_socket, c->c2.event_set, socket, (void*)&socket_shift, NULL); tun_set (c->c1.tuntap, c->c2.event_set, tuntap, (void*)&tun_shift, NULL); #ifdef ENABLE_MANAGEMENT if (management) management_socket_set (management, c->c2.event_set, (void*)&management_shift, NULL); #endif /* * Possible scenarios: * (1) tcp/udp port has data available to read * (2) tcp/udp port is ready to accept more data to write * (3) tun dev has data available to read * (4) tun dev is ready to accept more data to write * (5) we received a signal (handler sets signal_received) * (6) timeout (tv) expired */ c->c2.event_set_status = ES_ERROR; if (!c->sig->signal_received) { if (!(flags & IOW_CHECK_RESIDUAL) || !socket_read_residual (c->c2.link_socket)) { int status; #ifdef ENABLE_DEBUG if (check_debug_level (D_EVENT_WAIT)) show_wait_status (c); #endif /* * Wait for something to happen. */ status = event_wait (c->c2.event_set, &c->c2.timeval, esr, SIZE(esr)); check_status (status, "event_wait", NULL, NULL); if (status > 0) { int i; c->c2.event_set_status = 0; for (i = 0; i < status; ++i) { const struct event_set_return *e = &esr[i]; c->c2.event_set_status |= ((e->rwflags & 3) << *((int*)e->arg)); } } else if (status == 0) { c->c2.event_set_status = ES_TIMEOUT; } } else { c->c2.event_set_status = SOCKET_READ; } } /* 'now' should always be a reasonably up-to-date timestamp */ update_time (); /* set signal_received if a signal was received */ if (c->c2.event_set_status & ES_ERROR) get_signal (&c->sig->signal_received); dmsg (D_EVENT_WAIT, "I/O WAIT status=0x%04x", c->c2.event_set_status); }
void scanlinepattern (int y, int n, byte * pattern) { int x, i; byte mode; Point * temppoints; Point * points; byte top, bottom; i = 0; mode = 0; temppoints = malloc(n); top = 0; bottom = 0; for (x = 0; x < SCREEN_WIDTH; x++) { if (mode == 0) { if (getcolor(x,y) == LINE_COLOR) { // pengecekan garis lurus atau menekuk if (getcolor(x-1,y-1) == LINE_COLOR || getcolor(x,y-1) == LINE_COLOR || getcolor(x+1,y-1) == LINE_COLOR) { top++; } if (getcolor(x-1,y+1) == LINE_COLOR || getcolor(x,y+1) == LINE_COLOR || getcolor(x+1,y+1) == LINE_COLOR) { bottom++; } // pengecekan garis berlanjut pada sumbu x atau tidak if (getcolor(x+1,y) == LINE_COLOR) { // mencari titik ujung dari garis yang berlanjut pada sumbu x while (getcolor(x+1,y) == LINE_COLOR) { x++; } // mengecek lagi garis lurus atau menekuk // if (top == 0) // { if (getcolor(x-1,y-1) == LINE_COLOR || getcolor(x,y-1) == LINE_COLOR || getcolor(x+1,y-1) == LINE_COLOR) { top++; } // } // else if (bottom == 0) // { if (getcolor(x-1,y+1) == LINE_COLOR || getcolor(x,y+1) == LINE_COLOR || getcolor(x+1,y+1) == LINE_COLOR) { bottom++; } // } } // pengecekan apakah titik merupakan titik potong atau tidak if (top == 1 && bottom == 1) { temppoints[i].x = x; temppoints[i].y = y; i++; mode = 1; top = 0; bottom = 0; } else { top = 0; bottom = 0; } } } else if (mode == 1) { if (getcolor(x,y) == 0) { putpixel(x,y,pattern[x]); } else { temppoints[i].x = x; temppoints[i].y = y; i++; // pengecekan garis lurus atau menekuk if (getcolor(x-1,y-1) == LINE_COLOR || getcolor(x,y-1) == LINE_COLOR || getcolor(x+1,y-1) == LINE_COLOR) { top++; } if (getcolor(x-1,y+1) == LINE_COLOR || getcolor(x,y+1) == LINE_COLOR || getcolor(x+1,y+1) == LINE_COLOR) { bottom++; } // pengecekan garis berlanjut pada sumbu x atau tidak if (getcolor(x+1,y) == LINE_COLOR) { // mencari titik ujung dari garis yang berlanjut pada sumbu x while (getcolor(x+1,y) == LINE_COLOR) { x++; } temppoints[i].x = x; temppoints[i].y = y; i++; // mengecek lagi garis lurus atau menekuk // if (top == 0) // { if (getcolor(x-1,y-1) == LINE_COLOR || getcolor(x,y-1) == LINE_COLOR || getcolor(x+1,y-1) == LINE_COLOR) { top++; } // } // else if (bottom == 0) // { if (getcolor(x-1,y+1) == LINE_COLOR || getcolor(x,y+1) == LINE_COLOR || getcolor(x+1,y+1) == LINE_COLOR) { bottom++; } // } } // pengecekan apakah mode pewarnaan berlanjut atau tidak if (top == 1 && bottom == 1) { mode = 0; top = 0; bottom = 0; } else { top = 0; bottom = 0; } } } } points = malloc(i-1); for (i = 0; i < SIZE(points); i++) { points[i] = temppoints[i]; } }
GenotypeErrorModel::GenotypeErrorModel(const vector<vector<UBYTE> > & data) : _matrices(SIZE(data), Matrix<double>(NB_GENOTYPES_WITH_ZZ, NB_GENOTYPES_NO_ZZ)) { }
void nh_timeout() { register struct prop *upp; int sleeptime; int m_idx; int baseluck = (flags.moonphase == FULL_MOON) ? 1 : 0; if (flags.friday13) baseluck -= 1; if (u.uluck != baseluck && moves % (u.uhave.amulet || u.ugangr ? 300 : 600) == 0) { /* Cursed luckstones stop bad luck from timing out; blessed luckstones * stop good luck from timing out; normal luckstones stop both; * neither is stopped if you don't have a luckstone. * Luck is based at 0 usually, +1 if a full moon and -1 on Friday 13th */ register int time_luck = stone_luck(FALSE); boolean nostone = !carrying(LUCKSTONE) && !stone_luck(TRUE); if(u.uluck > baseluck && (nostone || time_luck < 0)) u.uluck--; else if(u.uluck < baseluck && (nostone || time_luck > 0)) u.uluck++; } if(u.uinvulnerable) return; /* things past this point could kill you */ if(Stoned) stoned_dialogue(); if(Slimed) slime_dialogue(); if(Vomiting) vomiting_dialogue(); if(Strangled) choke_dialogue(); if(u.mtimedone && !--u.mtimedone) { if (Unchanging) u.mtimedone = rnd(100*youmonst.data->mlevel + 1); else rehumanize(); } if(u.ucreamed) u.ucreamed--; /* Dissipate spell-based protection. */ if (u.usptime) { if (--u.usptime == 0 && u.uspellprot) { u.usptime = u.uspmtime; u.uspellprot--; find_ac(); if (!Blind) Norep("The %s haze around you %s.", hcolor(NH_GOLDEN), u.uspellprot ? "becomes less dense" : "disappears"); } } #ifdef STEED if (u.ugallop) { if (--u.ugallop == 0L && u.usteed) pline("%s stops galloping.", Monnam(u.usteed)); } #endif for(upp = u.uprops; upp < u.uprops+SIZE(u.uprops); upp++) if((upp->intrinsic & TIMEOUT) && !(--upp->intrinsic & TIMEOUT)) { switch(upp - u.uprops){ case STONED: if (delayed_killer && !killer) { killer = delayed_killer; delayed_killer = 0; } if (!killer) { /* leaving killer_format would make it "petrified by petrification" */ killer_format = NO_KILLER_PREFIX; killer = "killed by petrification"; } done(STONING); break; case SLIMED: if (delayed_killer && !killer) { killer = delayed_killer; delayed_killer = 0; } if (!killer) { killer_format = NO_KILLER_PREFIX; killer = "turned into green slime"; } done(TURNED_SLIME); break; case VOMITING: make_vomiting(0L, TRUE); break; case SICK: You("die from your illness."); killer_format = KILLED_BY_AN; killer = u.usick_cause; if ((m_idx = name_to_mon(killer)) >= LOW_PM) { if (type_is_pname(&mons[m_idx])) { killer_format = KILLED_BY; } else if (mons[m_idx].geno & G_UNIQ) { killer = the(killer); Strcpy(u.usick_cause, killer); killer_format = KILLED_BY; } } u.usick_type = 0; done(POISONING); break; case FAST: if (!Very_fast) You_feel("yourself slowing down%s.", Fast ? " a bit" : ""); break; case CONFUSION: HConfusion = 1; /* So make_confused works properly */ make_confused(0L, TRUE); stop_occupation(); break; case STUNNED: HStun = 1; make_stunned(0L, TRUE); stop_occupation(); break; case BLINDED: Blinded = 1; make_blinded(0L, TRUE); stop_occupation(); break; case INVIS: newsym(u.ux,u.uy); if (!Invis && !BInvis && !Blind) { You(!See_invisible ? "are no longer invisible." : "can no longer see through yourself."); stop_occupation(); } break; case SEE_INVIS: set_mimic_blocking(); /* do special mimic handling */ see_monsters(); /* make invis mons appear */ newsym(u.ux,u.uy); /* make self appear */ stop_occupation(); break; case WOUNDED_LEGS: heal_legs(); stop_occupation(); break; case HALLUC: HHallucination = 1; (void) make_hallucinated(0L, TRUE, 0L); stop_occupation(); break; case SLEEPING: if (unconscious() || Sleep_resistance) HSleeping += rnd(100); else if (Sleeping) { You("fall asleep."); sleeptime = rnd(20); fall_asleep(-sleeptime, TRUE); HSleeping += sleeptime + rnd(100); } break; case LEVITATION: (void) float_down(I_SPECIAL|TIMEOUT, 0L); break; case STRANGLED: killer_format = KILLED_BY; killer = (u.uburied) ? "suffocation" : "strangulation"; done(DIED); break; case FUMBLING: /* call this only when a move took place. */ /* otherwise handle fumbling msgs locally. */ if (u.umoved && !Levitation) { slip_or_trip(); nomul(-2); nomovemsg = ""; /* The more you are carrying the more likely you * are to make noise when you fumble. Adjustments * to this number must be thoroughly play tested. */ if ((inv_weight() > -500)) { You("make a lot of noise!"); wake_nearby(); } } /* from outside means slippery ice; don't reset counter if that's the only fumble reason */ HFumbling &= ~FROMOUTSIDE; if (Fumbling) HFumbling += rnd(20); break; case DETECT_MONSTERS: see_monsters(); break; } } run_timers(); }
static void dofsizes(int fd, struct fs *super, char *name) { ino_t inode, maxino; union dinode *dp; daddr_t sz, ksz; struct fsizes *fp, **fsp; int i; maxino = super->fs_ncg * super->fs_ipg - 1; #ifdef COMPAT if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) errx(1, "allocate fsize structure"); #endif /* COMPAT */ for (inode = 0; inode < maxino; inode++) { errno = 0; if ((dp = get_inode(fd,super,inode)) #ifdef COMPAT && ((DIP(super, dp, di_mode) & IFMT) == IFREG || (DIP(super, dp, di_mode) & IFMT) == IFDIR) #else /* COMPAT */ && !isfree(super, dp) #endif /* COMPAT */ ) { sz = estimate ? virtualblocks(super, dp) : actualblocks(super, dp); #ifdef COMPAT if (sz >= FSZCNT) { fsizes->fsz_count[FSZCNT-1]++; fsizes->fsz_sz[FSZCNT-1] += sz; } else { fsizes->fsz_count[sz]++; fsizes->fsz_sz[sz] += sz; } #else /* COMPAT */ ksz = SIZE(sz); for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) { if (ksz < fp->fsz_last) break; } if (!fp || ksz < fp->fsz_first) { if (!(fp = (struct fsizes *) malloc(sizeof(struct fsizes)))) errx(1, "allocate fsize structure"); fp->fsz_next = *fsp; *fsp = fp; fp->fsz_first = rounddown(ksz, FSZCNT); fp->fsz_last = fp->fsz_first + FSZCNT; for (i = FSZCNT; --i >= 0;) { fp->fsz_count[i] = 0; fp->fsz_sz[i] = 0; } } fp->fsz_count[ksz % FSZCNT]++; fp->fsz_sz[ksz % FSZCNT] += sz; #endif /* COMPAT */ } else if (errno) { err(1, "%s", name); } } sz = 0; for (fp = fsizes; fp; fp = fp->fsz_next) { for (i = 0; i < FSZCNT; i++) { if (fp->fsz_count[i]) printf("%jd\t%jd\t%d\n", (intmax_t)(fp->fsz_first + i), (intmax_t)fp->fsz_count[i], SIZE(sz += fp->fsz_sz[i])); } } }
/* * Find the appropriate kernel-only "root_table" unwind_table, * and pass it to populate_local_tables() to do the heavy lifting. */ static int gather_in_memory_unwind_tables(void) { int i, cnt, found; struct syment *sp, *root_tables[10]; char *root_table_buf; char buf[BUFSIZE]; ulong name; STRUCT_SIZE_INIT(unwind_table, "unwind_table"); MEMBER_OFFSET_INIT(unwind_table_core, "unwind_table", "core"); MEMBER_OFFSET_INIT(unwind_table_init, "unwind_table", "init"); MEMBER_OFFSET_INIT(unwind_table_address, "unwind_table", "address"); MEMBER_OFFSET_INIT(unwind_table_size, "unwind_table", "size"); MEMBER_OFFSET_INIT(unwind_table_link, "unwind_table", "link"); MEMBER_OFFSET_INIT(unwind_table_name, "unwind_table", "name"); if (INVALID_SIZE(unwind_table) || INVALID_MEMBER(unwind_table_core) || INVALID_MEMBER(unwind_table_init) || INVALID_MEMBER(unwind_table_address) || INVALID_MEMBER(unwind_table_size) || INVALID_MEMBER(unwind_table_link) || INVALID_MEMBER(unwind_table_name)) { if (CRASHDEBUG(1)) error(NOTE, "unwind_table structure has changed, or does not exist in this kernel\n"); return 0; } /* * Unfortunately there are two kernel root_table symbols. */ if (!(cnt = get_syment_array("root_table", root_tables, 10))) return 0; root_table_buf = GETBUF(SIZE(unwind_table)); for (i = found = 0; i < cnt; i++) { sp = root_tables[i]; if (!readmem(sp->value, KVADDR, root_table_buf, SIZE(unwind_table), "root unwind_table", RETURN_ON_ERROR|QUIET)) goto gather_failed; name = ULONG(root_table_buf + OFFSET(unwind_table_name)); if (read_string(name, buf, strlen("kernel")+1) && STREQ("kernel", buf)) { found++; if (CRASHDEBUG(1)) fprintf(fp, "root_table name: %lx [%s]\n", name, buf); break; } } if (!found) goto gather_failed; cnt = populate_local_tables(sp->value, root_table_buf); FREEBUF(root_table_buf); return cnt; gather_failed: FREEBUF(root_table_buf); return 0; }
/* the tsurugi of muramasa or vorpal blade hit someone */ static boolean artifact_hit_behead(struct monst *magr, struct monst *mdef, struct obj *otmp, int *dmgptr, int dieroll) { boolean youattack = (magr == &youmonst); boolean youdefend = (mdef == &youmonst); boolean vis = (!youattack && magr && cansee(magr->mx, magr->my)) || (!youdefend && cansee(mdef->mx, mdef->my)) || (youattack && u.uswallow && mdef == u.ustuck && !Blind); const char *wepdesc; char hittee[BUFSZ]; strcpy(hittee, youdefend ? "you" : mon_nam(mdef)); /* We really want "on a natural 20" but Nethack does it in reverse from AD&D. */ if (otmp->oartifact == ART_TSURUGI_OF_MURAMASA && dieroll == 1) { wepdesc = "The razor-sharp blade"; /* not really beheading, but so close, why add another SPFX */ if (youattack && u.uswallow && mdef == u.ustuck) { pline("You slice %s wide open!", mon_nam(mdef)); *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER; return TRUE; } if (!youdefend) { /* allow normal cutworm() call to add extra damage */ if (notonhead) return FALSE; if (bigmonst(mdef->data)) { if (youattack) pline("You slice deeply into %s!", mon_nam(mdef)); else if (vis) pline("%s cuts deeply into %s!", Monnam(magr), hittee); *dmgptr *= 2; return TRUE; } *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER; pline("%s cuts %s in half!", wepdesc, mon_nam(mdef)); otmp->dknown = TRUE; return TRUE; } else { if (bigmonst(youmonst.data)) { pline("%s cuts deeply into you!", magr ? Monnam(magr) : wepdesc); *dmgptr *= 2; return TRUE; } /* Players with negative AC's take less damage instead * of just not getting hit. We must add a large enough * value to the damage so that this reduction in * damage does not prevent death. */ *dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER; pline("%s cuts you in half!", wepdesc); otmp->dknown = TRUE; return TRUE; } } else if (otmp->oartifact == ART_VORPAL_BLADE && (dieroll == 1 || mdef->data == &mons[PM_JABBERWOCK])) { static const char * const behead_msg[2] = { "%s beheads %s!", "%s decapitates %s!" }; if (youattack && u.uswallow && mdef == u.ustuck) return FALSE; wepdesc = artilist[ART_VORPAL_BLADE].name; if (!youdefend) { if (!has_head(mdef->data) || notonhead || u.uswallow) { if (youattack) pline("Somehow, you miss %s wildly.", mon_nam(mdef)); else if (vis) pline("Somehow, %s misses wildly.", mon_nam(magr)); *dmgptr = 0; return (boolean)(youattack || vis); } if (noncorporeal(mdef->data) || amorphous(mdef->data)) { pline("%s slices through %s %s.", wepdesc, s_suffix(mon_nam(mdef)), mbodypart(mdef,NECK)); return TRUE; } *dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER; pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc, mon_nam(mdef)); otmp->dknown = TRUE; return TRUE; } else { if (!has_head(youmonst.data)) { pline("Somehow, %s misses you wildly.", magr ? mon_nam(magr) : wepdesc); *dmgptr = 0; return TRUE; } if (noncorporeal(youmonst.data) || amorphous(youmonst.data)) { pline("%s slices through your %s.", wepdesc, body_part(NECK)); return TRUE; } *dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER; pline(behead_msg[rn2(SIZE(behead_msg))], wepdesc, "you"); otmp->dknown = TRUE; /* Should amulets fall off? */ return TRUE; } } return FALSE; }
/* * Transfer the relevant data from the kernel and module unwind_table * structures to the local_unwind_table structures. */ static int populate_local_tables(ulong root, char *buf) { struct list_data list_data, *ld; int i, cnt; ulong *table_list; ulong vaddr; struct local_unwind_table *tp; ld = &list_data; BZERO(ld, sizeof(struct list_data)); ld->start = root; ld->member_offset = OFFSET(unwind_table_link); ld->flags = RETURN_ON_LIST_ERROR; if (CRASHDEBUG(1)) ld->flags |= VERBOSE; hq_open(); cnt = do_list(ld); if (cnt == -1) { error(WARNING, "UNWIND: failed to gather unwind_table list"); return 0; } table_list = (ulong *)GETBUF(cnt * sizeof(ulong)); cnt = retrieve_list(table_list, cnt); hq_close(); if (!(local_unwind_tables = malloc(sizeof(struct local_unwind_table) * cnt))) { error(WARNING, "cannot malloc unwind_table space (%d tables)\n", cnt); FREEBUF(table_list); return 0; } for (i = 0; i < cnt; i++, tp++) { if (!readmem(table_list[i], KVADDR, buf, SIZE(unwind_table), "unwind_table", RETURN_ON_ERROR|QUIET)) { error(WARNING, "cannot read unwind_table\n"); goto failed; } tp = &local_unwind_tables[i]; /* * Copy the required table info for find_table(). */ BCOPY(buf + OFFSET(unwind_table_core), (char *)&tp->core.pc, sizeof(ulong)*2); BCOPY(buf + OFFSET(unwind_table_init), (char *)&tp->init.pc, sizeof(ulong)*2); BCOPY(buf + OFFSET(unwind_table_size), (char *)&tp->size, sizeof(ulong)); /* * Then read the DWARF CFI data. */ vaddr = ULONG(buf + OFFSET(unwind_table_address)); if (!(tp->address = malloc(tp->size))) { error(WARNING, "cannot malloc unwind_table space\n"); goto failed; break; } if (!readmem(vaddr, KVADDR, tp->address, tp->size, "DWARF CFI data", RETURN_ON_ERROR|QUIET)) { error(WARNING, "cannot read unwind_table data\n"); goto failed; } } unwind_tables_cnt = cnt; if (CRASHDEBUG(7)) dump_local_unwind_tables(); failed: FREEBUF(table_list); return unwind_tables_cnt; }
/* * This is the main function for the port share proxy background process. */ static void port_share_proxy (const in_addr_t hostaddr, const int port, const socket_descriptor_t sd_control) { if (send_control (sd_control, RESPONSE_INIT_SUCCEEDED) >= 0) { void *sd_control_marker = (void *)1; int maxevents = 256; struct event_set *es; struct event_set_return esr[64]; struct proxy_connection *list = NULL; time_t last_housekeeping = 0; msg (D_PS_PROXY, "PORT SHARE PROXY: proxy starting"); es = event_set_init (&maxevents, 0); event_ctl (es, sd_control, EVENT_READ, sd_control_marker); while (true) { int n_events; struct timeval tv; time_t current; tv.tv_sec = 10; tv.tv_usec = 0; n_events = event_wait (es, &tv, esr, SIZE(esr)); /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait returned %d", n_events);*/ current = time(NULL); if (n_events > 0) { int i; for (i = 0; i < n_events; ++i) { const struct event_set_return *e = &esr[i]; if (e->arg == sd_control_marker) { if (!control_message_from_parent (sd_control, &list, es, hostaddr, port)) goto done; } else { struct proxy_connection *pc = (struct proxy_connection *)e->arg; if (pc->defined) proxy_connection_io_dispatch (pc, e->rwflags, es); } } } else if (n_events < 0) { dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait failed"); } if (current > last_housekeeping) { proxy_list_housekeeping (&list); last_housekeeping = current; } } done: proxy_list_close (&list); event_free (es); } msg (D_PS_PROXY, "PORT SHARE PROXY: proxy exiting"); }
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, game_state *state, int dir, game_ui *ui, float animtime, float flashtime) { int w = state->par.w /*, a = w*w */; int i, x, y; if (!ds->started) { /* * The initial contents of the window are not guaranteed and * can vary with front ends. To be on the safe side, all * games should start by drawing a big background-colour * rectangle covering the whole window. */ draw_rect(dr, 0, 0, SIZE(w), SIZE(w), COL_BACKGROUND); draw_update(dr, 0, 0, SIZE(w), SIZE(w)); ds->started = TRUE; } check_errors(state, ds->errtmp); /* * Work out what data each tile should contain. */ for (i = 0; i < (w+2)*(w+2); i++) ds->tiles[i] = 0; /* completely blank square */ /* The clue squares... */ for (i = 0; i < 4*w; i++) { long tile = state->clues->clues[i]; CLUEPOS(x, y, i, w); if (ds->errtmp[(y+1)*(w+2)+(x+1)]) tile |= DF_ERROR; ds->tiles[(y+1)*(w+2)+(x+1)] = tile; } /* ... and the main grid. */ for (y = 0; y < w; y++) { for (x = 0; x < w; x++) { long tile = DF_PLAYAREA; if (state->grid[y*w+x]) tile |= state->grid[y*w+x]; else tile |= (long)state->pencil[y*w+x] << DF_PENCIL_SHIFT; if (ui->hshow && ui->hx == x && ui->hy == y) tile |= (ui->hpencil ? DF_HIGHLIGHT_PENCIL : DF_HIGHLIGHT); if (state->clues->immutable[y*w+x]) tile |= DF_IMMUTABLE; if (flashtime > 0 && (flashtime <= FLASH_TIME/3 || flashtime >= FLASH_TIME*2/3)) tile |= DF_HIGHLIGHT; /* completion flash */ if (ds->errtmp[(y+1)*(w+2)+(x+1)]) tile |= DF_ERROR; ds->tiles[(y+1)*(w+2)+(x+1)] = tile; } } /* * Now actually draw anything that needs to be changed. */ for (y = 0; y < w+2; y++) { for (x = 0; x < w+2; x++) { long tl, tr, bl, br; int i = y*(w+2)+x; tr = ds->tiles[y*(w+2)+x]; tl = (x == 0 ? 0 : ds->tiles[y*(w+2)+(x-1)]); br = (y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+x]); bl = (x == 0 || y == w+1 ? 0 : ds->tiles[(y+1)*(w+2)+(x-1)]); if (ds->drawn[i*4] != tl || ds->drawn[i*4+1] != tr || ds->drawn[i*4+2] != bl || ds->drawn[i*4+3] != br) { clip(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE); draw_tile(dr, ds, state->clues, x-1, y-1, tr); if (x > 0) draw_tile(dr, ds, state->clues, x-2, y-1, tl); if (y <= w) draw_tile(dr, ds, state->clues, x-1, y, br); if (x > 0 && y <= w) draw_tile(dr, ds, state->clues, x-2, y, bl); unclip(dr); draw_update(dr, COORD(x-1), COORD(y-1), TILESIZE, TILESIZE); ds->drawn[i*4] = tl; ds->drawn[i*4+1] = tr; ds->drawn[i*4+2] = bl; ds->drawn[i*4+3] = br; } } } }
static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, SAK, decr_console, incr_console, spawn_console, bare_num; static void_fnp spec_fn_table[] = { do_null, enter, show_ptregs, show_mem, show_state, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, SAK, decr_console, incr_console, spawn_console, bare_num }; /* maximum values each key_handler can handle */ const int max_vals[] = { 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1, NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, 255, NR_LOCK - 1 }; const int NR_TYPES = SIZE(max_vals); static void put_queue(int); static unsigned char handle_diacr(unsigned char); /* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */ static struct pt_regs * pt_regs; static inline void kb_wait(void) {
static int domonnoise(struct monst *mtmp) { const char *pline_msg = 0, /* Monnam(mtmp) will be prepended */ *verbl_msg = 0; /* verbalize() */ const struct permonst *ptr = mtmp->data; char verbuf[BUFSZ]; /* presumably nearness and sleep checks have already been made */ if (!flags.soundok) return 0; if (is_silent(ptr)) return 0; /* Make sure its your role's quest quardian; adjust if not */ if (ptr->msound == MS_GUARDIAN && ptr != &pm_guardian) { int mndx = monsndx(ptr); ptr = &mons[genus(mndx, 1)]; } /* be sure to do this before talking; the monster might teleport away, in which case we want to check its pre-teleport position */ if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); switch (ptr->msound) { case MS_ORACLE: return doconsult(mtmp); case MS_PRIEST: priest_talk(mtmp); break; case MS_LEADER: case MS_NEMESIS: case MS_GUARDIAN: quest_chat(mtmp); break; case MS_SELL: /* pitch, pay, total */ shk_chat(mtmp); break; case MS_VAMPIRE: { /* vampire messages are varied by tameness, peacefulness, and time of night */ boolean isnight = night(); boolean kindred = (Upolyd && (u.umonnum == PM_VAMPIRE || u.umonnum == PM_VAMPIRE_LORD)); boolean nightchild = (Upolyd && (u.umonnum == PM_WOLF || u.umonnum == PM_WINTER_WOLF || u.umonnum == PM_WINTER_WOLF_CUB)); const char *racenoun = (flags.female && urace.individual.f) ? urace.individual. f : (urace.individual.m) ? urace.individual.m : urace.noun; if (mtmp->mtame) { if (kindred) { sprintf(verbuf, "Good %s to you Master%s", isnight ? "evening" : "day", isnight ? "!" : ". Why do we not rest?"); verbl_msg = verbuf; } else { sprintf(verbuf, "%s%s", nightchild ? "Child of the night, " : "", midnight()? "I can stand this craving no longer!" : isnight ? "I beg you, help me satisfy this growing craving!" : "I find myself growing a little weary."); verbl_msg = verbuf; } } else if (mtmp->mpeaceful) { if (kindred && isnight) { sprintf(verbuf, "Good feeding %s!", flags.female ? "sister" : "brother"); verbl_msg = verbuf; } else if (nightchild && isnight) { sprintf(verbuf, "How nice to hear you, child of the night!"); verbl_msg = verbuf; } else verbl_msg = "I only drink... potions."; } else { int vampindex; static const char *const vampmsg[] = { /* These first two (0 and 1) are specially handled below */ "I vant to suck your %s!", "I vill come after %s without regret!", /* other famous vampire quotes can follow here if desired */ }; if (kindred) verbl_msg = "This is my hunting ground that you dare to prowl!"; else if (youmonst.data == &mons[PM_SILVER_DRAGON] || youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) { /* Silver dragons are silver in color, not made of silver */ sprintf(verbuf, "%s! Your silver sheen does not frighten me!", youmonst.data == &mons[PM_SILVER_DRAGON] ? "Fool" : "Young Fool"); verbl_msg = verbuf; } else { vampindex = rn2(SIZE(vampmsg)); if (vampindex == 0) { sprintf(verbuf, vampmsg[vampindex], body_part(BLOOD)); verbl_msg = verbuf; } else if (vampindex == 1) { sprintf(verbuf, vampmsg[vampindex], Upolyd ? an(mons[u.umonnum]. mname) : an(racenoun)); verbl_msg = verbuf; } else verbl_msg = vampmsg[vampindex]; } } } break; case MS_WERE: if (flags.moonphase == FULL_MOON && (night() ^ !rn2(13))) { pline("%s throws back %s head and lets out a blood curdling %s!", Monnam(mtmp), mhis(mtmp), ptr == &mons[PM_HUMAN_WERERAT] ? "shriek" : "howl"); wake_nearto(mtmp->mx, mtmp->my, 11 * 11); } else pline_msg = "whispers inaudibly. All you can make out is \"moon\"."; break; case MS_BARK: if (flags.moonphase == FULL_MOON && night()) { pline_msg = "howls."; } else if (mtmp->mpeaceful) { if (mtmp->mtame && (mtmp->mconf || mtmp->mflee || mtmp->mtrapped || moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5)) pline_msg = "whines."; else if (mtmp->mtame && EDOG(mtmp)->hungrytime > moves + 1000) pline_msg = "yips."; else { if (mtmp->data != &mons[PM_DINGO]) /* dingos do not actually bark */ pline_msg = "barks."; } } else { pline_msg = "growls."; } break; case MS_MEW: if (mtmp->mtame) { if (mtmp->mconf || mtmp->mflee || mtmp->mtrapped || mtmp->mtame < 5) pline_msg = "yowls."; else if (moves > EDOG(mtmp)->hungrytime) pline_msg = "meows."; else if (EDOG(mtmp)->hungrytime > moves + 1000) pline_msg = "purrs."; else pline_msg = "mews."; break; } /* else FALLTHRU */ case MS_GROWL: pline_msg = mtmp->mpeaceful ? "snarls." : "growls!"; break; case MS_ROAR: pline_msg = mtmp->mpeaceful ? "snarls." : "roars!"; break; case MS_SQEEK: pline_msg = "squeaks."; break; case MS_SQAWK: if (ptr == &mons[PM_RAVEN] && !mtmp->mpeaceful) verbl_msg = "Nevermore!"; else pline_msg = "squawks."; break; case MS_HISS: if (!mtmp->mpeaceful) pline_msg = "hisses!"; else return 0; /* no sound */ break; case MS_BUZZ: pline_msg = mtmp->mpeaceful ? "drones." : "buzzes angrily."; break; case MS_GRUNT: pline_msg = "grunts."; break; case MS_NEIGH: if (mtmp->mtame < 5) pline_msg = "neighs."; else if (moves > EDOG(mtmp)->hungrytime) pline_msg = "whinnies."; else pline_msg = "whickers."; break; case MS_WAIL: pline_msg = "wails mournfully."; break; case MS_GURGLE: pline_msg = "gurgles."; break; case MS_BURBLE: pline_msg = "burbles."; break; case MS_SHRIEK: pline_msg = "shrieks."; aggravate(); break; case MS_IMITATE: pline_msg = "imitates you."; break; case MS_BONES: pline("%s rattles noisily.", Monnam(mtmp)); pline("You freeze for a moment."); nomul(-2, "scared by rattling"); nomovemsg = 0; /* default: "You can move again." */ break; case MS_LAUGH: { static const char *const laugh_msg[4] = { "giggles.", "chuckles.", "snickers.", "laughs.", }; pline_msg = laugh_msg[rn2(4)]; } break; case MS_MUMBLE: pline_msg = "mumbles incomprehensibly."; break; case MS_DJINNI: if (mtmp->mtame) { verbl_msg = "Sorry, I'm all out of wishes."; } else if (mtmp->mpeaceful) { if (ptr == &mons[PM_WATER_DEMON]) pline_msg = "gurgles."; else verbl_msg = "I'm free!"; } else verbl_msg = "This will teach you not to disturb me!"; break; case MS_BOAST: /* giants */ if (!mtmp->mpeaceful) { switch (rn2(4)) { case 0: pline("%s boasts about %s gem collection.", Monnam(mtmp), mhis(mtmp)); break; case 1: pline_msg = "complains about a diet of mutton."; break; default: pline_msg = "shouts \"Fee Fie Foe Foo!\" and guffaws."; wake_nearto(mtmp->mx, mtmp->my, 7 * 7); break; } break; } /* else FALLTHRU */ case MS_HUMANOID: if (!mtmp->mpeaceful) { if (In_endgame(&u.uz) && is_mplayer(ptr)) { mplayer_talk(mtmp); break; } else return 0; /* no sound */ } /* Generic peaceful humanoid behaviour. */ if (mtmp->mflee) pline_msg = "wants nothing to do with you."; else if (mtmp->mhp < mtmp->mhpmax / 4) pline_msg = "moans."; else if (mtmp->mconf || mtmp->mstun) verbl_msg = !rn2(3) ? "Huh?" : rn2(2) ? "What?" : "Eh?"; else if (!mtmp->mcansee) verbl_msg = "I can't see!"; else if (mtmp->mtrapped) { struct trap *t = t_at(level, mtmp->mx, mtmp->my); if (t) t->tseen = 1; verbl_msg = "I'm trapped!"; } else if (mtmp->mhp < mtmp->mhpmax / 2) pline_msg = "asks for a potion of healing."; else if (mtmp->mtame && !mtmp->isminion && moves > EDOG(mtmp)->hungrytime) verbl_msg = "I'm hungry."; /* Specific monsters' interests */ else if (is_elf(ptr)) pline_msg = "curses orcs."; else if (is_dwarf(ptr)) pline_msg = "talks about mining."; else if (likes_magic(ptr)) pline_msg = "talks about spellcraft."; else if (ptr->mlet == S_CENTAUR) pline_msg = "discusses hunting."; else switch (monsndx(ptr)) { case PM_HOBBIT: pline_msg = (mtmp->mhpmax - mtmp->mhp >= 10) ? "complains about unpleasant dungeon conditions." : "asks you about the One Ring."; break; case PM_ARCHEOLOGIST: pline_msg = "describes a recent article in \"Spelunker Today\" magazine."; break; case PM_TOURIST: verbl_msg = "Aloha."; break; default: pline_msg = "discusses dungeon exploration."; break; } break; case MS_SEDUCE: if (ptr->mlet != S_NYMPH && flags.seduce_enabled && could_seduce(mtmp, &youmonst, NULL) == 1) { doseduce(mtmp); break; } switch ((poly_gender() != (int)mtmp->female) ? rn2(3) : 0) { case 2: verbl_msg = "Hello, sailor."; break; case 1: pline_msg = "comes on to you."; break; default: pline_msg = "cajoles you."; } break; case MS_ARREST: if (mtmp->mpeaceful) verbalize("Just the facts, %s.", flags.female ? "Ma'am" : "Sir"); else { static const char *const arrest_msg[3] = { "Anything you say can be used against you.", "You're under arrest!", "Stop in the name of the Law!", }; verbl_msg = arrest_msg[rn2(3)]; } break; case MS_BRIBE: if (mtmp->mpeaceful && !mtmp->mtame) { demon_talk(mtmp); break; } /* fall through */ case MS_CUSS: if (!mtmp->mpeaceful) cuss(mtmp); break; case MS_SPELL: /* deliberately vague, since it's not actually casting any spell */ pline_msg = "seems to mutter a cantrip."; break; case MS_NURSE: if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) verbl_msg = "Put that weapon away before you hurt someone!"; else if (uarmc || uarm || uarmh || uarms || uarmg || uarmf) verbl_msg = Role_if(PM_HEALER) ? "Doc, I can't help you unless you cooperate." : "Please undress so I can examine you."; else if (uarmu) verbl_msg = "Take off your shirt, please."; else verbl_msg = "Relax, this won't hurt a bit."; break; case MS_GUARD: if (money_cnt(invent)) verbl_msg = "Please drop that gold and follow me."; else verbl_msg = "Please follow me."; break; case MS_SOLDIER: { static const char *const soldier_foe_msg[3] = { "Resistance is useless!", "You're dog meat!", "Surrender!", }, *const soldier_pax_msg[3] = { "What lousy pay we're getting here!", "The food's not fit for Orcs!", "My feet hurt, I've been on them all day!", }; verbl_msg = mtmp->mpeaceful ? soldier_pax_msg[rn2(3)] : soldier_foe_msg[rn2(3)]; } break; case MS_RIDER: if (ptr == &mons[PM_DEATH] && !rn2(10)) pline_msg = "is busy reading a copy of Sandman #8."; else verbl_msg = "Who do you think you are, War?"; break; } if (pline_msg) pline("%s %s", Monnam(mtmp), pline_msg); else if (verbl_msg) verbalize(verbl_msg); return 1; }