static void parse_headers (Call *c, char **bufp, size_t *buf_lenp) { char *hdr, *buf_start = *bufp; Conn *s = c->conn; size_t hdr_len; Any_Type arg; while (get_line (c, bufp, buf_lenp) > 0) { hdr = s->line.iov_base; hdr_len = s->line.iov_len; if (!hdr_len) { /* empty header implies end of headers */ if (s->has_body) if (s->is_chunked) { s->content_length = 0; s->state = S_REPLY_CHUNKED; } else s->state = S_REPLY_DATA; else if (s->state == S_REPLY_CONTINUE) s->state = S_REPLY_HEADER; else s->state = S_REPLY_DONE; break; } /* process line as a regular header: */ switch (tolower (*hdr)) { case 'c': if (strncasecmp (hdr, "content-length:", 15) == 0) { hdr += 15; s->content_length = strtoul (hdr, 0, 10); if (!s->content_length) s->has_body = 0; } break; case 't': if (strncasecmp (hdr, "transfer-encoding:", 18) == 0) { hdr += 18; while (isspace (*hdr)) ++hdr; if (strcasecmp (hdr, "chunked") == 0) s->is_chunked = 1; else fprintf (stderr, "%s.parse_headers: unknown transfer " "encoding `%s'\n", prog_name, hdr); } break; } arg.vp = &s->line; event_signal (EV_CALL_RECV_HDR, (Object *) c, arg); if (s->state >= S_CLOSING) return; s->line.iov_len = 0; } c->reply.header_bytes += *bufp - buf_start; }
/* * Output a message to the top line of the screen. * * Break long messages into multiple pieces (40-72 chars). * * Allow multiple short messages to "share" the top line. * * Prompt the user to make sure he has a chance to read them. * * These messages are memorized for later reference (see above). * * We could do a "Term_fresh()" to provide "flicker" if needed. * * The global "msg_flag" variable can be cleared to tell us to "erase" any * "pending" messages still on the screen, instead of using "msg_flush()". * This should only be done when the user is known to have read the message. * * We must be very careful about using the "msg("%s", )" functions without * explicitly calling the special "msg("%s", NULL)" function, since this may * result in the loss of information if the screen is cleared, or if anything * is displayed on the top line. * * Hack -- Note that "msg("%s", NULL)" will clear the top line even if no * messages are pending. */ static void msg_print_aux(u16b type, const char *msg) { int n; char *t; char buf[1024]; byte color; int w, h; if (!Term) return; /* Obtain the size */ (void)Term_get_size(&w, &h); /* Hack -- Reset */ if (!msg_flag) message_column = 0; /* Message Length */ n = (msg ? strlen(msg) : 0); /* Hack -- flush when requested or needed */ if (message_column && (!msg || ((message_column + n) > (w - 8)))) { /* Flush */ msg_flush(message_column); /* Forget it */ msg_flag = FALSE; /* Reset */ message_column = 0; } /* No message */ if (!msg) return; /* Paranoia */ if (n > 1000) return; /* Memorize the message (if legal) */ if (character_generated && !(p_ptr->is_dead)) message_add(msg, type); /* Window stuff */ p_ptr->redraw |= (PR_MESSAGE); /* Copy it */ my_strcpy(buf, msg, sizeof(buf)); /* Analyze the buffer */ t = buf; /* Get the color of the message */ color = message_type_color(type); /* Split message */ while (n > w - 1) { char oops; int check, split; /* Default split */ split = w - 8; /* Find the rightmost split point */ for (check = (w / 2); check < w - 8; check++) if (t[check] == ' ') split = check; /* Save the split character */ oops = t[split]; /* Split the message */ t[split] = '\0'; /* Display part of the message */ Term_putstr(0, 0, split, color, t); /* Flush it */ msg_flush(split + 1); /* Restore the split character */ t[split] = oops; /* Insert a space */ t[--split] = ' '; /* Prepare to recurse on the rest of "buf" */ t += split; n -= split; } /* Display the tail of the message */ Term_putstr(message_column, 0, n, color, t); /* Remember the message */ msg_flag = TRUE; /* Remember the position */ message_column += n + 1; /* Send refresh event */ event_signal(EVENT_MESSAGE); }
/* * Examine a grid, return a keypress. * * The "mode" argument contains the "TARGET_LOOK" bit flag, which * indicates that the "space" key should scan through the contents * of the grid, instead of simply returning immediately. This lets * the "look" command get complete information, without making the * "target" command annoying. * * The "info" argument contains the "commands" which should be shown * inside the "[xxx]" text. This string must never be empty, or grids * containing monsters will be displayed with an extra comma. * * Note that if a monster is in the grid, we update both the monster * recall info and the health bar info to track that monster. * * This function correctly handles multiple objects per grid, and objects * and terrain features in the same grid, though the latter never happens. * * This function must handle blindness/hallucination. */ static ui_event_data target_set_interactive_aux(int y, int x, int mode, cptr info, bool list_floor_objects) { s16b this_o_idx, next_o_idx = 0; s16b this_x_idx, next_x_idx = 0; cptr s1, s2, s3; bool floored; u16b feat; ui_event_data query; char out_val[256]; char coords[20]; /* Describe the square location */ coords_desc(coords, sizeof(coords), y, x); /* Repeat forever */ while (1) { int i; char feat_name[80]; /* Terrain suffix for monsters and objects */ char terrain_suffix[200]; /* Temporary array of visible effects */ s16b x_seen[50]; u16b size_x_seen = 0; /* Paranoia */ query.key = ' '; /* Default */ s1 = "You see "; s2 = ""; s3 = "on "; /* The player */ if (cave_m_idx[y][x] < 0) { /* Description */ s1 = "You are "; /* Preposition */ s2 = "on "; } /* Feature (apply "mimic") */ feat = f_info[cave_feat[y][x]].f_mimic; /* Require knowledge about grid, or ability to see grid */ if (!(cave_info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x)) { /* Forget feature */ feat = FEAT_NONE; } else { /* Hack -- track the current feature */ feature_kind_track(feat); /* Window stuff */ p_ptr->redraw |= (PR_FEATURE); } /* Pick a prefix */ if (*s2 && (!feat_ff1_match(feat, FF1_MOVE) || !feat_ff1_match(feat, FF1_LOS) || feat_ff1_match(feat, FF1_SHOP | FF1_DOOR) || feat_ff2_match(feat, FF2_SHALLOW | FF2_DEEP) || feat_ff3_match(feat, FF3_NEED_TREE))) { s3 = "in "; } /* Get a default name */ if (feat <= FEAT_NONE) { my_strcpy(feat_name, "an unknown grid", sizeof(feat_name)); } /* Get the real name */ else { feature_desc(feat_name, sizeof (feat_name), feat, TRUE, FALSE); } /* List all effects in the grid */ for (this_x_idx = cave_x_idx[y][x]; this_x_idx; this_x_idx = next_x_idx) { effect_type *x_ptr; /* Get the effect */ x_ptr = &x_list[this_x_idx]; /* Get the next effect */ next_x_idx = x_ptr->next_x_idx; /* Describe it, if not hidden */ if (!(x_ptr->x_flags & (EF1_HIDDEN)) && x_ptr->x_f_idx) { /* Check for available space */ if (size_x_seen < N_ELEMENTS(x_seen)) { x_seen[size_x_seen++] = x_ptr->x_f_idx; } } } /* Prepare the terrain suffix for monsters and objects */ my_strcpy(terrain_suffix, format(" %s%s", s3, feat_name), sizeof(terrain_suffix)); /* Concat the collected effect names */ for (i = 0; i < size_x_seen; i++) { char x_name[80]; /* Obtain an object description */ feature_desc(x_name, sizeof(x_name), x_seen[i], TRUE, TRUE); /* First effect */ if (i == 0) { if ((feat == FEAT_NONE) || !feat_ff1_match(feat, FF1_MOVE) || cave_any_trap_bold(y, x)) { /* Basic info */ my_strcat(terrain_suffix, format(" with %s", x_name), sizeof(terrain_suffix)); } else { /* Basic info */ my_strcat(terrain_suffix, format(" beneath %s", x_name), sizeof(terrain_suffix)); } } /* Basic info */ else if (i < (size_x_seen - 1)) { my_strcat(terrain_suffix, format(", %s", x_name), sizeof(terrain_suffix)); } /* Basic info */ else { my_strcat(terrain_suffix, format(" and %s", x_name), sizeof(terrain_suffix)); } } /* Ignore the terrain suffix if certain things happen */ if ((size_x_seen == 0) && (feat <= FEAT_FLOOR)) { terrain_suffix[0] = '\0'; } /* Hack -- hallucination */ if (p_ptr->timed[TMD_IMAGE]) { cptr name = "something strange"; /* Display a message */ if (p_ptr->wizard) { strnfmt(out_val, sizeof(out_val), "%s%s%s, [%s] %s (%d:%d).", s1, s2, name, info, coords, y, x); } else { strnfmt(out_val, sizeof(out_val), "%s%s%s [%s], %s.", s1, s2, name, info, coords); } prt(out_val, 0, 0); move_cursor_relative(y, x); query = inkey_ex(); /* Stop on everything but "return" */ if ((query.key != '\n') && (query.key != '\r')) break; /* Repeat forever */ continue; } /* Actual monsters */ if (cave_m_idx[y][x] > 0) { monster_type *m_ptr = &mon_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; /* Visible */ if (m_ptr->ml) { bool recall = FALSE; char m_name[80]; if (m_ptr->mimic_k_idx) { /*get the description*/ mimic_desc_object(m_name, sizeof(m_name), m_ptr->mimic_k_idx); } else { /* Get the monster name ("a kobold") */ monster_desc(m_name, sizeof(m_name), m_ptr, 0x08); /* Hack -- track this monster race */ monster_race_track(m_ptr->r_idx); /* Hack -- health bar for this monster */ health_track(cave_m_idx[y][x]); /*Track the feature*/ feature_kind_track(cave_feat[y][x]); /* Window stuff */ p_ptr->redraw |= (PR_FEATURE); /* Hack -- handle stuff */ handle_stuff(); } /* Interact */ while (1) { if (recall) button_add("[CLEAR_RECALL]", 'r'); else button_add("[RECALL]", 'r'); if (cave_o_idx[y][x] > 0)button_add("[VIEW_FLOOR]", 'f'); event_signal(EVENT_MOUSEBUTTONS); /* Recall, but not mimics */ if ((recall) && (!(m_ptr->mimic_k_idx))) { /* Save screen */ screen_save(); /* Recall on screen */ screen_roff(m_ptr->r_idx); /* Hack -- Complete the prompt (again) */ Term_addstr(-1, TERM_WHITE, format(" [r,%s]", info)); /* Command */ query = inkey_ex(); /* Load screen */ screen_load(); } /* Normal */ else { /* Basic info */ strnfmt(out_val, sizeof(out_val), "%s%s%s", s1, s2, m_name); /* Describe the monster, unless a mimic */ if (!(m_ptr->mimic_k_idx)) { char buf[80]; look_mon_desc(buf, sizeof(buf), cave_m_idx[y][x]); /* Monster state, terrain suffix, options */ my_strcat(out_val, format(" (%s)%s [r,%s]", buf, terrain_suffix, info), sizeof(out_val)); } /* Mimics */ else { /* Terrain suffix, options */ my_strcat(out_val, format("%s [I,%s]", terrain_suffix, info), sizeof(out_val)); } /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } prt(out_val, 0, 0); /* Place cursor */ move_cursor_relative(y, x); /* Command */ query = inkey_ex(); } button_kill('r'); button_kill('f'); event_signal(EVENT_MOUSEBUTTONS); /* Handle fake object recall */ if (m_ptr->mimic_k_idx) { object_type body; object_type *o_ptr = &body; /* Validate input first */ if (query.key != 'I') break; /* Paranoia */ object_wipe(o_ptr); /* Prepare */ object_prep(o_ptr, m_ptr->mimic_k_idx); /* Fake history */ object_history(o_ptr, ORIGIN_FLOOR, 0); /* Clear prompt. Place cursor */ prt("", 0, 0); /* Show the fake info - EXPERIMENTAL */ object_info_screen(o_ptr); } /* Regular monsters */ else { /* Normal commands */ if (query.key != 'r') break; /* Toggle recall */ recall = !recall; } } /* Stop on everything but "return"/"space", or floor */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ') && (query.key != 'f')) break; /* continue with 'f' only if there are floor items....*/ if ((query.key == 'f') && (!cave_o_idx[y][x])) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s1 = "It is "; /* Hack -- take account of gender */ if (r_ptr->flags1 & (RF1_FEMALE)) s1 = "She is "; else if (r_ptr->flags1 & (RF1_MALE)) s1 = "He is "; /* Use a preposition */ s2 = "carrying "; /* Scan all objects being carried */ for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) { char o_name[80]; object_type *o_ptr; /* Get the object */ o_ptr = &o_list[this_o_idx]; /* Get the next object */ next_o_idx = o_ptr->next_o_idx; /*Don't let the player see certain objects (used for vault treasure)*/ if ((o_ptr->ident & (IDENT_HIDE_CARRY)) && (!p_ptr->wizard) && (!cheat_peek)) continue; /* Obtain an object description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Describe the object */ strnfmt(out_val, sizeof(out_val), "%s%s%s [%s]", s1, s2, o_name, info); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } prt(out_val, 0, 0); move_cursor_relative(y, x); query = inkey_ex(); /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s2 = "also carrying "; } /* Double break */ if (this_o_idx) break; /* Use a preposition */ s2 = "on "; } } /* Assume not floored */ floored = FALSE; /* Scan all objects in the grid */ if (TRUE) { int floor_list[MAX_FLOOR_STACK]; int floor_num; track_object(-floor_list[0]); handle_stuff(); /* Scan for floor objects */ floor_num = scan_floor(floor_list, MAX_FLOOR_STACK, y, x, 0x02); /* Actual pile */ if (floor_num > 1) { /* Floored */ floored = TRUE; /* Describe */ while (1) { /* Basic info */ strnfmt(out_val, sizeof(out_val), "%s%sa pile of %d objects%s [r,%s]", s1, s2, floor_num, terrain_suffix, info); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } prt(out_val, 0, 0); if (list_floor_objects) { /* Save screen */ screen_save(); /* Display */ show_floor(floor_list, floor_num, (OLIST_WEIGHT | OLIST_GOLD)); } move_cursor_relative(y, x); query = inkey_ex(); if (list_floor_objects) { screen_load(); } /* Display objects */ if (query.key == 'r') { int pos; pos = query.key - 'a'; if (0 <= pos && pos < floor_num) { track_object(-floor_list[pos]); handle_stuff(); } } /* Done */ break; } /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s1 = "It is "; /* Preposition */ s2 = "on "; } } /* Scan all objects in the grid */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; /* Get the object */ o_ptr = &o_list[this_o_idx]; /* Get the next object */ next_o_idx = o_ptr->next_o_idx; /* Skip objects if floored */ if (floored) continue; /* Describe it */ if (o_ptr->marked) { char o_name[80]; /* Obtain an object description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Basic info */ strnfmt(out_val, sizeof(out_val), "%s%s%s%s [I,%s]", s1, s2, o_name, terrain_suffix, info); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } /* Show object. Handle object recall */ while (TRUE) { /* Print the prompt */ prt(out_val, 0, 0); /* Move cursor to that location */ move_cursor_relative(y, x); /* Read input key */ query = inkey_ex(); /* No object recall */ if (query.key != 'I') break; /* Object recall. Clear the first line */ prt("", 0, 0); /* Do it */ object_info_screen(o_ptr); } /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s1 = "It is "; /* Plurals */ if (o_ptr->number != 1) s1 = "They are "; /* Preposition */ s2 = "on "; } } /* Double break */ if (this_o_idx) break; /* Display terrain */ if (TRUE) { u16b temp_feat; bool enable_recall; bool show_recall = FALSE; char temp_name[80]; /* * Display terrain and effects */ for (i = 0; i <= size_x_seen; i++) { /* Hack - This is the mark for the feature stored in cave_feat */ if (i == size_x_seen) { temp_feat = feat; /* Just copy the feature name */ my_strcpy(temp_name, feat_name, sizeof(temp_name)); } /* Any other value is an effect stored x_list */ else { temp_feat = x_seen[i]; /* Get the effect's name */ feature_desc(temp_name, sizeof(temp_name), temp_feat, TRUE, TRUE); } /* Don't display feature recall if the grid is unknown */ enable_recall = (temp_feat != FEAT_NONE); /* Handle recall */ while (TRUE) { /* Handle recall mode */ if (show_recall && enable_recall) { /* Save screen */ screen_save(); /* Recall feature on screen */ screen_feature_roff(temp_feat); } /* Display a message */ strnfmt(out_val, sizeof(out_val), "%s%s%s [%s%s]%s", s1, s2, temp_name, (enable_recall ? "r,": ""), info, (i < size_x_seen) ? " (more)": ""); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } /*Track this feature*/ feature_kind_track(temp_feat); /* Hack -- handle stuff */ handle_stuff(); prt(out_val, 0, 0); move_cursor_relative(y, x); query = inkey_ex(); /* Load screen if necessary */ if (show_recall && enable_recall) { screen_load(); } /* Stop on everything but the recall command, if enabled */ if (!enable_recall || (query.key != 'r')) break; /* Toggle recall */ show_recall = !show_recall; } /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; } } /* Hack -- handle stuff */ handle_stuff(); /* Stop on everything but "return" */ if ((query.key != '\n') && (query.key != '\r')) break; } /* Keep going */ return (query); }
/** * Drop (some of) a non-cursed inventory/equipment item "near" the current * location * * There are two cases here - a single object or entire stack is being dropped, * or part of a stack is being split off and dropped */ void inven_drop(struct object *obj, int amt) { int py = player->py; int px = player->px; struct object *dropped; bool none_left = false; bool quiver = false; char name[80]; char label; /* Error check */ if (amt <= 0) return; /* Check it is still held, in case there were two drop commands queued * for this item. This is in theory not ideal, but in practice should * be safe. */ if (!object_is_carried(player, obj)) return; /* Get where the object is now */ label = gear_to_label(obj); /* Is it in the quiver? */ if (object_is_in_quiver(player, obj)) quiver = true; /* Not too many */ if (amt > obj->number) amt = obj->number; /* Take off equipment, don't combine */ if (object_is_equipped(player->body, obj)) inven_takeoff(obj); /* Get the object */ dropped = gear_object_for_use(obj, amt, false, &none_left); /* Describe the dropped object */ object_desc(name, sizeof(name), dropped, ODESC_PREFIX | ODESC_FULL); /* Message */ msg("You drop %s (%c).", name, label); /* Describe what's left */ if (dropped->artifact) { object_desc(name, sizeof(name), dropped, ODESC_FULL | ODESC_SINGULAR); msg("You no longer have the %s (%c).", name, label); } else if (none_left) { /* Play silly games to get the right description */ int number = dropped->number; dropped->number = 0; object_desc(name, sizeof(name), dropped, ODESC_PREFIX | ODESC_FULL); msg("You have %s (%c).", name, label); dropped->number = number; } else { object_desc(name, sizeof(name), obj, ODESC_PREFIX | ODESC_FULL); msg("You have %s (%c).", name, label); } /* Drop it near the player */ drop_near(cave, &dropped, 0, py, px, false); /* Sound for quiver objects */ if (quiver) sound(MSG_QUIVER); event_signal(EVENT_INVENTORY); event_signal(EVENT_EQUIPMENT); }
/* * Destroy the scheduler subsystem. All waitable threads at signaled to terminate. * this function blocks untill all waitable threads have terminated. */ DWORD scheduler_destroy(VOID) { DWORD result = ERROR_SUCCESS; DWORD index = 0; DWORD count = 0; LIST * jlist = list_create(); THREAD * thread = NULL; WaitableEntry * entry = NULL; dprintf("[SCHEDULER] entering scheduler_destroy."); if (schedulerThreadList == NULL) { return ERROR_SUCCESS; } lock_acquire(schedulerThreadList->lock); count = list_count(schedulerThreadList); for (index = 0; index < count; index++) { thread = (THREAD *)list_get(schedulerThreadList, index); if (thread == NULL) { continue; } list_push(jlist, thread); entry = (WaitableEntry *)thread->parameter1; if (!entry->running) { event_signal(entry->resume); } thread_sigterm(thread); } lock_release(schedulerThreadList->lock); dprintf("[SCHEDULER] scheduler_destroy, joining all waitable threads..."); while (TRUE) { dprintf("[SCHEDULER] scheduler_destroy, popping off another item from thread list..."); thread = (THREAD *)list_pop(jlist); if (thread == NULL) { break; } dprintf("[SCHEDULER] scheduler_destroy, joining thread 0x%08X...", thread); thread_join(thread); } dprintf("[SCHEDULER] scheduler_destroy, destroying lists..."); list_destroy(jlist); list_destroy(schedulerThreadList); schedulerThreadList = NULL; dprintf("[SCHEDULER] leaving scheduler_destroy."); return result; }
/** * Save a simple text screendump. */ static void do_cmd_save_screen_text(void) { int y, x; int a = 0; wchar_t c = L' '; ang_file *fff; char buf[1024]; char *p; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt"); fff = file_open(buf, MODE_WRITE, FTYPE_TEXT); if (!fff) return; /* Save screen */ screen_save(); /* Dump the screen */ for (y = 0; y < 24; y++) { p = buf; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Terminate */ *p = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Dump the screen */ for (y = 0; y < 24; y++) { /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = hack[a & 0x0F]; } /* Terminate */ buf[x] = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Close it */ file_close(fff); /* Message */ msg("Screen dump saved."); event_signal(EVENT_MESSAGE_FLUSH); /* Load screen */ screen_load(); }
static void fastboot_notify(struct udc_gadget *gadget, unsigned event) { if (event == UDC_EVENT_ONLINE) { event_signal(&usb_online, 0); } }
/** * The main game loop. * * This function will run until the player needs to enter a command, or closes * the game, or the character dies. */ void run_game_loop(void) { /* Tidy up after the player's command */ process_player_cleanup(); /* Keep processing the player until they use some energy or * another command is needed */ while (player->upkeep->playing) { process_player(); if (player->upkeep->energy_use) break; else return; } /* The player may still have enough energy to move, so we run another * player turn before processing the rest of the world */ while (player->energy >= z_info->move_energy) { /* Do any necessary animations */ event_signal(EVENT_ANIMATE); /* Process monster with even more energy first */ process_monsters(cave, player->energy + 1); if (player->is_dead || !player->upkeep->playing || player->upkeep->generate_level) break; /* Process the player until they use some energy */ while (player->upkeep->playing) { process_player(); if (player->upkeep->energy_use) break; else return; } } /* Now that the player's turn is fully complete, we run the main loop * until player input is needed again */ while (true) { notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); /* Process the rest of the world, give the player energy and * increment the turn counter unless we need to stop playing or * generate a new level */ if (player->is_dead || !player->upkeep->playing) return; else if (!player->upkeep->generate_level) { /* Process the rest of the monsters */ process_monsters(cave, 0); /* Mark all monsters as ready to act when they have the energy */ reset_monsters(); /* Refresh */ notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); if (player->is_dead || !player->upkeep->playing) return; /* Process the world every ten turns */ if (!(turn % 10) && !player->upkeep->generate_level) { process_world(cave); /* Refresh */ notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); if (player->is_dead || !player->upkeep->playing) return; } /* Give the player some energy */ player->energy += turn_energy(player->state.speed); /* Count game turns */ turn++; } /* Make a new level if requested */ if (player->upkeep->generate_level) { if (character_dungeon) on_leave_level(); cave_generate(&cave, player); on_new_level(); player->upkeep->generate_level = false; } /* If the player has enough energy to move they now do so, after * any monsters with more energy take their turns */ while (player->energy >= z_info->move_energy) { /* Do any necessary animations */ event_signal(EVENT_ANIMATE); /* Process monster with even more energy first */ process_monsters(cave, player->energy + 1); if (player->is_dead || !player->upkeep->playing || player->upkeep->generate_level) break; /* Process the player until they use some energy */ while (player->upkeep->playing) { process_player(); if (player->upkeep->energy_use) break; else return; } } } }
void display_server_unpause(void) { event_signal(&e_continue, true); }
void test_event_loop_enter() { scheduler_t* scheduler; scheduler = scheduler_init(testdb, NULL); scheduler_agent_config(scheduler); event_loop_t* vl = event_loop_get(); int retval = 0; call_num = 0; samp_num = 0; event_signal(NULL, NULL); event_signal(terminate_event, NULL); retval = event_loop_enter(scheduler, sample_callback, NULL); FO_ASSERT_EQUAL(retval, 0x0); FO_ASSERT_EQUAL(call_num,1); FO_ASSERT_TRUE(vl->terminated); FO_ASSERT_FALSE(vl->occupied); event_signal(sample_event, NULL); event_signal(terminate_event, NULL); retval = event_loop_enter(scheduler, sample_callback, NULL); FO_ASSERT_EQUAL(retval, 0x0); FO_ASSERT_EQUAL(samp_num, 1); FO_ASSERT_EQUAL(call_num, 3); vl->occupied = 0; vl->terminated = 0; event_signal(terminate_event, NULL); retval = event_loop_enter(scheduler, sample_callback, NULL); FO_ASSERT_EQUAL(retval, 0x0); FO_ASSERT_EQUAL(samp_num, 1); FO_ASSERT_EQUAL(call_num, 4); vl->occupied = 0; vl->terminated = 0; samp_num = 0; call_num = 0; event_signal(sample_event, NULL); event_signal(sample_event, NULL); event_signal(other_event, NULL); event_signal(sample_event, NULL); event_signal(sample_event, NULL); event_signal(other_event, NULL); event_signal(terminate_event, NULL); retval = event_loop_enter(scheduler, sample_callback, NULL); FO_ASSERT_EQUAL(retval, 0x0); FO_ASSERT_EQUAL(samp_num, 2); FO_ASSERT_EQUAL(call_num, 7); vl->occupied = 0; vl->terminated = 1; samp_num = 0; call_num = 0; event_signal(sample_event, NULL); event_signal(sample_event, NULL); event_signal(other_event, NULL); event_signal(sample_event, NULL); event_signal(sample_event, NULL); event_signal(other_event, NULL); event_signal(terminate_event, NULL); retval = event_loop_enter(scheduler, sample_callback, NULL); FO_ASSERT_EQUAL(retval, 0x0); FO_ASSERT_EQUAL(samp_num, 2); FO_ASSERT_EQUAL(call_num, 7); scheduler_destroy(scheduler); }
/** * Process player commands from the command queue, finishing when there is a * command using energy (any regular game command), or we run out of commands * and need another from the user, or the character changes level or dies, or * the game is stopped. * * Notice the annoying code to handle "pack overflow", which * must come first just in case somebody manages to corrupt * the savefiles by clever use of menu commands or something. (Can go? NRM) * * Notice the annoying code to handle "monster memory" changes, * which allows us to avoid having to update the window flags * every time we change any internal monster memory field, and * also reduces the number of times that the recall window must * be redrawn. */ void process_player(void) { /* Check for interrupts */ player_resting_complete_special(player); event_signal(EVENT_CHECK_INTERRUPT); /* Repeat until energy is reduced */ do { /* Refresh */ notice_stuff(player); handle_stuff(player); event_signal(EVENT_REFRESH); /* Hack -- Pack Overflow */ pack_overflow(NULL); /* Assume free turn */ player->upkeep->energy_use = 0; /* Dwarves detect treasure */ if (player_has(player, PF_SEE_ORE)) { /* Only if they are in good shape */ if (!player->timed[TMD_IMAGE] && !player->timed[TMD_CONFUSED] && !player->timed[TMD_AMNESIA] && !player->timed[TMD_STUN] && !player->timed[TMD_PARALYZED] && !player->timed[TMD_TERROR] && !player->timed[TMD_AFRAID]) effect_simple(EF_DETECT_GOLD, "3d3", 1, 0, 0, NULL); } /* Paralyzed or Knocked Out player gets no turn */ if ((player->timed[TMD_PARALYZED]) || (player->timed[TMD_STUN] >= 100)) cmdq_push(CMD_SLEEP); /* Prepare for the next command */ if (cmd_get_nrepeats() > 0) event_signal(EVENT_COMMAND_REPEAT); else { /* Check monster recall */ if (player->upkeep->monster_race) player->upkeep->redraw |= (PR_MONSTER); /* Place cursor on player/target */ event_signal(EVENT_REFRESH); } /* Get a command from the queue if there is one */ if (!cmdq_pop(CMD_GAME)) break; if (!player->upkeep->playing) break; process_player_cleanup(); } while (!player->upkeep->energy_use && !player->is_dead && !player->upkeep->generate_level); /* Notice stuff (if needed) */ notice_stuff(player); }
static void colors_browse_hook(int oid, void *db, const region *loc) { event_signal(EVENT_MESSAGE_FLUSH); clear_from(1); }
/** * Pick up objects and treasure on the floor. -LM- * * Scan the list of objects in that floor grid. Pick up gold automatically. * Pick up objects automatically until backpack space is full if * auto-pickup option is on, otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If not picking up anything, indicate objects on the floor. Do the same * thing if we don't have room for anything. * * Pick up multiple objects using Tim Baker's menu system. Recursively * call this function (forcing menus for any number of objects) until * objects are gone, backpack is full, or player is satisfied. * * We keep track of number of objects picked up to calculate time spent. * This tally is incremented even for automatic pickup, so we are careful * (in "dungeon.c" and elsewhere) to handle pickup as either a separate * automated move or a no-cost part of the stay still or 'g'et command. * * Note the lack of chance for the character to be disturbed by unmarked * objects. They are truly "unknown". * * \param obj is the object to pick up. * \param menu is whether to present a menu to the player */ static byte player_pickup_item(struct object *obj, bool menu) { int py = player->py; int px = player->px; struct object *current = NULL; int floor_max = z_info->floor_size + 1; struct object **floor_list = mem_zalloc(floor_max * sizeof(*floor_list)); int floor_num = 0; int i; int can_pickup = 0; bool call_function_again = FALSE; bool domsg = TRUE; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; /* Always pickup gold, effortlessly */ player_pickup_gold(); /* Nothing else to pick up -- return */ if (!square_object(cave, py, px)) { mem_free(floor_list); return objs_picked_up; } /* Tally objects that can be picked up.*/ floor_num = scan_floor(floor_list, floor_max, py, px, 0x08, NULL); for (i = 0; i < floor_num; i++) if (inven_carry_okay(floor_list[i])) can_pickup++; if (!can_pickup) { /* Can't pick up, but probably want to know what's there. */ event_signal(EVENT_SEEFLOOR); mem_free(floor_list); return objs_picked_up; } /* Use the item that we are given, if it is on the floor. */ if (square_holds_object(cave, py, px, obj)) current = obj; /* Use a menu interface for multiple objects, or pickup single objects */ if (!menu && !current) { if (floor_num > 1) menu = TRUE; else current = floor_list[0]; } /* Display a list if requested. */ if (menu && !current) { const char *q, *s; struct object *obj1; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; if (!get_item(&obj1, q, s, CMD_PICKUP, inven_carry_okay, USE_FLOOR)) { mem_free(floor_list); return (objs_picked_up); } current = obj1; call_function_again = TRUE; /* With a list, we do not need explicit pickup messages */ domsg = FALSE; } /* Pick up object, if legal */ if (current) { /* Pick up the object */ player_pickup_aux(current, domsg); /* Indicate an object picked up. */ objs_picked_up = 1; } /* * If requested, call this function recursively. Count objects picked * up. Force the display of a menu in all cases. */ if (call_function_again) objs_picked_up += player_pickup_item(NULL, TRUE); mem_free(floor_list); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
status_t accelerometer_request_data(void) { status_t result = event_signal(&accelerometer_event, true); return result; }
/** * @brief Update function called after every event * * The heart of the scheduler, the actual scheduling algorithm. This will be * passed to the event loop as a call back and will be called every time an event * is executed. Therefore the code should be light weight since it will be run * very frequently. * * @TODO: * currently this will only grab a job and create a single agent to execute * the job. * * @TODO: allow for runonpfile jobs to have multiple agents based on size * @TODO: allow for job preemption. The scheduler can pause jobs, allow it * @TODO: allow for specific hosts to be chosen. */ void scheduler_update(scheduler_t* scheduler) { /* queue used to hold jobs if an exclusive job enters the system */ static job_t* job = NULL; static host_t* host = NULL; static int lockout = 0; /* locals */ int n_agents = g_tree_nnodes(scheduler->agents); int n_jobs = active_jobs(scheduler->job_list); /* check to see if we are in and can exit the startup state */ if(scheduler->s_startup && n_agents == 0) { event_signal(database_update_event, NULL); scheduler->s_startup = 0; } /* check if we are able to close the scheduler */ if(closing && n_agents == 0 && n_jobs == 0) { event_loop_terminate(); return; } if(lockout && n_agents == 0 && n_jobs == 0) lockout = 0; if(job == NULL && !lockout) { while((job = peek_job(scheduler->job_queue)) != NULL) { // check if the agent is required to run on local host if(is_meta_special( g_tree_lookup(scheduler->meta_agents, job->agent_type), SAG_LOCAL)) { host = g_tree_lookup(scheduler->host_list, LOCAL_HOST); if(!(host->running < host->max)) { job = NULL; break; } } // check if the job is required to run on a specific machine else if((job->required_host != NULL)) { host = g_tree_lookup(scheduler->host_list, job->required_host); if(host != NULL) { if(!(host->running < host->max)) { job = NULL; break; } } else { //log_printf("ERROR %s.%d: jq_pk %d jq_host '%s' not in the agent list!\n", // __FILE__, __LINE__, job->id, job->required_host); job->message = "ERROR: jq_host not in the agent list!"; job_fail_event(scheduler, job); job = NULL; break; } } // the generic case, this can run anywhere, find a place else if((host = get_host(&(scheduler->host_queue), 1)) == NULL) { job = NULL; break; } next_job(scheduler->job_queue); if(is_meta_special( g_tree_lookup(scheduler->meta_agents, job->agent_type), SAG_EXCLUSIVE)) { V_SCHED("JOB_INIT: exclusive, postponing initialization\n"); break; } V_SCHED("Starting JOB[%d].%s\n", job->id, job->agent_type); agent_init(scheduler, host, job); job = NULL; } } if(job != NULL && n_agents == 0 && n_jobs == 0) { agent_init(scheduler, host, job); lockout = 1; job = NULL; host = NULL; } if(scheduler->s_pause) { scheduler->s_startup = 1; scheduler->s_pause = 0; } }
/** * Attempt to open the given chest at the given location * * Assume there is no monster blocking the destination * * Returns TRUE if repeated commands may continue */ bool do_cmd_open_chest(int y, int x, struct object *obj) { int i, j; bool flag = TRUE; bool more = FALSE; /* Attempt to unlock it */ if (obj->pval > 0) { /* Assume locked, and thus not open */ flag = FALSE; /* Get the "disarm" factor */ i = player->state.skills[SKILL_DISARM]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* Extract the difficulty */ j = i - obj->pval; /* Always have a small chance of success */ if (j < 2) j = 2; /* Success -- May still have traps */ if (randint0(100) < j) { msgt(MSG_LOCKPICK, "You have picked the lock."); player_exp_gain(player, 1); flag = TRUE; } else { /* We may continue repeating */ more = TRUE; event_signal(EVENT_INPUT_FLUSH); msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); } } /* Allowed to open */ if (flag) { /* Apply chest traps, if any */ chest_trap(y, x, obj); /* Let the Chest drop items */ chest_death(y, x, obj); /* Ignore chest if autoignore calls for it */ player->upkeep->notice |= PN_IGNORE; } /* Empty chests were always ignored in ignore_item_okay so we * might as well ignore it here */ if (obj->pval == 0) obj->ignore = TRUE; /* Redraw chest, to be on the safe side (it may have been ignored) */ square_light_spot(cave, y, x); /* Result */ return (more); }
/** * Hack -- load a screen dump from a file * * ToDo: Add support for loading/saving screen-dumps with graphics * and pseudo-graphics. Allow the player to specify the filename * of the dump. */ void do_cmd_load_screen(void) { int i, y, x; int a = 0; wchar_t c = L' '; bool okay = TRUE; ang_file *fp; char buf[1024]; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt"); fp = file_open(buf, MODE_READ, FTYPE_TEXT); if (!fp) return; /* Save screen */ screen_save(); /* Clear the screen */ Term_clear(); /* Load the screen */ for (y = 0; okay && (y < 24); y++) { /* Get a line of data */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Show each row */ for (x = 0; x < 79; x++) { text_mbstowcs(&c, &buf[x], 1); /* Put the attr/char */ Term_draw(x, y, COLOUR_WHITE, c); } } /* Get the blank line */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Dump the screen */ for (y = 0; okay && (y < 24); y++) { /* Get a line of data */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < BASIC_COLORS; i++) /* Use attr matches */ if (hack[i] == buf[x]) a = i; /* Put the attr/char */ Term_draw(x, y, a, c); } } /* Close it */ file_close(fp); /* Message */ msg("Screen dump loaded."); event_signal(EVENT_MESSAGE_FLUSH); /* Load screen */ screen_load(); }
int write_storage_proc(void *arg) { u8* data = 0; u32 data_len = 0; char msg[128]; u64 image_offset = 0; u32 round = 0; //dprintf(DBG_DCACHE, " --[%d] Enter write_storage_proc \n", TIME_STAMP); for (;;) { dprintf(DBG_DCACHE, " --[%d]Wait ID:%d cache to read, \n", TIME_STAMP, ctx.flipIdxR); event_wait(&(ctx.dual_cache[ctx.flipIdxR].content_available)); dprintf(DBG_DCACHE, " --[%d]Obtain ID:%d cache to read, \n", TIME_STAMP, ctx.flipIdxR); if(ctx.b_error) { sprintf(msg, "\nError USB?\n"); goto error; } //if has something to write if(ctx.dual_cache[ctx.flipIdxR].content_length !=0 || ctx.dual_cache[ctx.flipIdxR].padding_length !=0) { data = (u8*)(ctx.dual_cache[ctx.flipIdxR].cache_buf); data_len = ctx.dual_cache[ctx.flipIdxR].content_length; #ifdef MTK_SECURITY_SW_SUPPORT if(!security_check(&data, &data_len, image_offset, NULL)) { //security error. sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error()); goto error; } #endif image_offset += ctx.dual_cache[ctx.flipIdxR].content_length; data -= ctx.dual_cache[ctx.flipIdxR].padding_length; data_len += ctx.dual_cache[ctx.flipIdxR].padding_length; //if data_len==0, secure img tail met. dprintf(DBG_DCACHE, " --[%d]Write ID:%d to EMMC \n", TIME_STAMP, ctx.flipIdxR); #ifdef MTK_SECURITY_SW_SUPPORT if(!write_data(data, data_len, sec_lib_security_get_img_total_size())) #else if(!write_data(data, data_len, 0)) #endif { //error sprintf(msg, "\nWrite data error. \n"); goto error; } } //last package, should return; if (ctx.dual_cache[ctx.flipIdxR].content_length == 0) { dprintf(DBG_DCACHE, " --[%d]Write EMMC Fin\n", TIME_STAMP); data_len = 0; #ifdef MTK_SECURITY_SW_SUPPORT security_check(&data, &data_len, image_offset, NULL); //notify security check that is the end. #endif if(ctx.boot_like_info.is_boot_like_image) { //boot image need download_size to flash. download_size = sto_info.to_write_data_len; //cache using is over, so copy boot image to download_base memcpy(download_base, ctx.boot_like_info.boot_like_image_address, download_size); } event_signal(&ctx.dual_cache[0].cache_available, SIGNAL_RESCHEDULE);//prevent from dead lock. event_signal(&ctx.dual_cache[1].cache_available, SIGNAL_RESCHEDULE); event_signal(&ctx.thr_end_ev, SIGNAL_RESCHEDULE); return 0; } round++; dprintf(DBG_DCACHE, " --[%d]Notify ID:%d cache writeable\n", TIME_STAMP, ctx.flipIdxR); event_signal(&ctx.dual_cache[ctx.flipIdxR].cache_available, SIGNAL_RESCHEDULE); //make this cache writeable again. ctx.flipIdxR = cache_shift(ctx.flipIdxR); //change next buffer. } return 0; error: dprintf(DBG_LV, msg); display_info(msg); abort_engine(&ctx); return (-1); }
/** * Hack -- change name */ void do_cmd_change_name(void) { ui_event ke; int mode = 0; const char *p; bool more = true; /* Prompt */ p = "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"; /* Save screen */ screen_save(); /* Forever */ while (more) { /* Display the player */ display_player(mode); /* Prompt */ Term_putstr(2, 23, -1, COLOUR_WHITE, p); /* Query */ ke = inkey_ex(); if ((ke.type == EVT_KBRD)||(ke.type == EVT_BUTTON)) { switch (ke.key.code) { case ESCAPE: more = false; break; case 'c': { if(arg_force_name) msg("You are not allowed to change your name!"); else { char namebuf[32] = ""; /* Set player name */ if (get_character_name(namebuf, sizeof namebuf)) my_strcpy(player->full_name, namebuf, sizeof(player->full_name)); } break; } case 'f': { char buf[1024]; char fname[80]; /* Get the filesystem-safe name and append .txt */ player_safe_name(fname, sizeof(fname), player->full_name, false); my_strcat(fname, ".txt", sizeof(fname)); if (get_file(fname, buf, sizeof buf)) { if (dump_save(buf)) msg("Character dump successful."); else msg("Character dump failed!"); } break; } case 'h': case ARROW_LEFT: case ' ': mode = (mode + 1) % INFO_SCREENS; break; case 'l': case ARROW_RIGHT: mode = (mode - 1) % INFO_SCREENS; break; } } else if (ke.type == EVT_MOUSE) { if (ke.mouse.button == 1) { /* Flip through the screens */ mode = (mode + 1) % INFO_SCREENS; } else if (ke.mouse.button == 2) { /* exit the screen */ more = false; } else { /* Flip backwards through the screens */ mode = (mode - 1) % INFO_SCREENS; } } /* Flush messages */ event_signal(EVENT_MESSAGE_FLUSH); } /* Load screen */ screen_load(); }
BOOL read_usb_proc(void *arg) { char msg[128]; u32 bytes_already_read = 0; u32 data_length = *((u32*)arg); u32 bytes_read = 0; int bytes_read_once = 0; u32 bytes_left = 0; dprintf(DBG_DCACHE, "++[%d]Enter read_usb_proc\n", TIME_STAMP); while (bytes_already_read < data_length) { dprintf(DBG_DCACHE, "++[%d]Wait ID:%d cache to write\n", TIME_STAMP, ctx.flipIdxW); event_wait(&(ctx.dual_cache[ctx.flipIdxW].cache_available)); dprintf(DBG_DCACHE, "++[%d]Obtain ID:%d cache to write, \n", TIME_STAMP, ctx.flipIdxW); if(ctx.b_error) { sprintf(msg, "\nError Write?\n"); goto error; } bytes_read = 0; bytes_left = data_length - bytes_already_read; bytes_left = bytes_left >= CACHE_PAGE_SIZE ? CACHE_PAGE_SIZE : bytes_left; dprintf(DBG_DCACHE, "++[%d]READ USB to ID:%d\n", TIME_STAMP, ctx.flipIdxW); while(bytes_left > 0) { bytes_read_once = usb_read(ctx.dual_cache[ctx.flipIdxW].cache_buf + bytes_read, bytes_left); if (bytes_read_once < 0) { abort_engine(&ctx); dprintf(DBG_LV, "Read USB error.\n"); display_info("\nRead USB error\n"); fastboot_state = STATE_ERROR; return FALSE; } bytes_left -= bytes_read_once; bytes_read += bytes_read_once; } ctx.dual_cache[ctx.flipIdxW].content_length = bytes_read; bytes_already_read += bytes_read; dprintf(DBG_DCACHE, "++[%d]Notify ID:%d cache readable\n", TIME_STAMP, ctx.flipIdxW); event_signal(&ctx.dual_cache[ctx.flipIdxW].content_available, SIGNAL_RESCHEDULE); ctx.flipIdxW = cache_shift(ctx.flipIdxW); //change next buffer. display_progress("\rTransfer Data", bytes_already_read, data_length); } if(bytes_already_read != data_length) { dprintf(DBG_LV, "ASSERT error. bytes_already_read != data_length\n"); //cause assert. *((int*)0x00) = 0; } dprintf(DBG_DCACHE, "++[%d]USB read Fin\n", TIME_STAMP); //last package. //must wait for this can write again. event_wait(&(ctx.dual_cache[ctx.flipIdxW].cache_available)); ctx.dual_cache[ctx.flipIdxW].content_length = 0; event_signal(&ctx.dual_cache[ctx.flipIdxW].content_available, SIGNAL_RESCHEDULE); return TRUE; error: dprintf(DBG_LV, msg); display_info(msg); abort_engine(&ctx); return FALSE; }
static void req_complete(struct udc_request *req, unsigned actual, int status) { txn_status = status; req->length = actual; event_signal(&txn_done, 0); }
/* * Pick up objects and treasure on the floor. -LM- * * Called with pickup: * 0 to act according to the player's settings * 1 to quickly pickup single objects or present a menu for more * 2 to force a menu for any number of objects * * Scan the list of objects in that floor grid. Pick up gold automatically. * Pick up objects automatically until backpack space is full if * auto-pickup option is on, Otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If not picking up anything, indicate objects on the floor. Show more * details if the "OPT(pickup_detail)" option is set. Do the same thing if we * don't have room for anything. * * [This paragraph is not true, intentional?] * If we are picking up objects automatically, and have room for at least * one, allow the "OPT(pickup_detail)" option to display information about objects * and prompt the player. Otherwise, automatically pick up a single object * or use a menu for more than one. * * Pick up multiple objects using Tim Baker's menu system. Recursively * call this function (forcing menus for any number of objects) until * objects are gone, backpack is full, or player is satisfied. * * We keep track of number of objects picked up to calculate time spent. * This tally is incremented even for automatic pickup, so we are careful * (in "dungeon.c" and elsewhere) to handle pickup as either a separate * automated move or a no-cost part of the stay still or 'g'et command. * * Note the lack of chance for the character to be disturbed by unmarked * objects. They are truly "unknown". */ byte py_pickup(int pickup) { int py = p_ptr->py; int px = p_ptr->px; s16b this_o_idx = 0; size_t floor_num = 0; int floor_list[MAX_FLOOR_STACK + 1]; size_t i; int can_pickup = 0; bool call_function_again = FALSE; bool domsg = TRUE; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; /* Nothing else to pick up -- return */ if (!cave->o_idx[py][px]) return objs_picked_up; /* Tally objects that can be picked up.*/ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03); for (i = 0; i < floor_num; i++) { can_pickup += inven_carry_okay(object_byid(floor_list[i])); } if (!can_pickup) { /* Can't pick up, but probably want to know what's there. */ event_signal(EVENT_SEEFLOOR); return objs_picked_up; } /* Use a menu interface for multiple objects, or pickup single objects */ if (pickup == 1) { if (floor_num > 1) pickup = 2; else this_o_idx = floor_list[0]; } /* Display a list if requested. */ if (pickup == 2) { const char *q, *s; int item; /* Restrict the choices */ item_tester_hook = inven_carry_okay; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR)) return (objs_picked_up); this_o_idx = 0 - item; call_function_again = TRUE; /* With a list, we do not need explicit pickup messages */ domsg = FALSE; } /* Pick up object, if legal */ if (this_o_idx) { /* Pick up the object */ py_pickup_aux(this_o_idx, domsg); /* Indicate an object picked up. */ objs_picked_up = 1; } /* * If requested, call this function recursively. Count objects picked * up. Force the display of a menu in all cases. */ if (call_function_again) objs_picked_up += py_pickup(2); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
/* * Signal a waitable object. */ DWORD scheduler_signal_waitable( HANDLE waitable, SchedularSignal signal ) { DWORD index = 0; DWORD count = 0; THREAD * thread = NULL; WaitableEntry * entry = NULL; DWORD result = ERROR_NOT_FOUND; dprintf( "[SCHEDULER] entering scheduler_signal_waitable( 0x%08X )", waitable ); if( schedulerThreadList == NULL || !waitable ) return ERROR_INVALID_HANDLE; lock_acquire( schedulerThreadList->lock ); count = list_count( schedulerThreadList ); for( index=0 ; index < count ; index++ ) { thread = (THREAD *)list_get( schedulerThreadList, index ); if( thread == NULL ) continue; entry = (WaitableEntry *)thread->parameter1; if( entry == NULL ) continue; if( entry->waitable == waitable ) { dprintf( "[SCHEDULER] scheduler_signal_waitable: signaling waitable = 0x%08X, thread = 0x%08X", waitable, thread ); if( signal == Pause ) { if( entry->running ) { dprintf( "[SCHEDULER] scheduler_signal_waitable: thread running, pausing. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->pause->handle ); event_signal( entry->pause ); } else { dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already paused. waitable = 0x%08X, thread = 0x%08X", waitable, thread ); } } else { if( !entry->running ) { dprintf( "[SCHEDULER] scheduler_signal_waitable: thread paused, resuming. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->resume->handle ); event_signal( entry->resume ); } if( signal == Stop ) { dprintf( "[SCHEDULER] scheduler_signal_waitable: stopping thread. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, thread->sigterm->handle ); thread_sigterm( thread ); } else { dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already running. waitable = 0x%08X, thread = 0x%08X", waitable, thread ); } } result = ERROR_SUCCESS; break; } } lock_release( schedulerThreadList->lock ); dprintf( "[SCHEDULER] leaving scheduler_signal_waitable" ); return result; }
/** * Perform the basic "open" command on doors * * Assume there is no monster blocking the destination * * Returns true if repeated commands may continue */ static bool do_cmd_open_aux(int y, int x) { int i, j; bool more = false; /* Verify legality */ if (!do_cmd_open_test(y, x)) return (false); /* Locked door */ if (square_islockeddoor(cave, y, x)) { /* Disarm factor */ i = player->state.skills[SKILL_DISARM_PHYS]; /* Penalize some conditions */ if (player->timed[TMD_BLIND] || no_light()) i = i / 10; if (player->timed[TMD_CONFUSED] || player->timed[TMD_IMAGE]) i = i / 10; /* Extract the lock power */ j = square_door_power(cave, y, x); /* Extract the difficulty XXX XXX XXX */ j = i - (j * 4); /* Always have a small chance of success */ if (j < 2) j = 2; if (randint0(100) < j) { /* Message */ msgt(MSG_LOCKPICK, "You have picked the lock."); /* Open the door */ square_open_door(cave, y, x); /* Update the visuals */ square_memorize(cave, y, x); square_light_spot(cave, y, x); player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Experience */ /* Removed to avoid exploit by repeatedly locking and unlocking */ /* player_exp_gain(player, 1); */ } else { event_signal(EVENT_INPUT_FLUSH); /* Message */ msgt(MSG_LOCKPICK_FAIL, "You failed to pick the lock."); /* We may keep trying */ more = true; } } else { /* Closed door */ square_open_door(cave, y, x); square_memorize(cave, y, x); square_light_spot(cave, y, x); player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS); sound(MSG_OPENDOOR); } /* Result */ return (more); }
void uart_a0_putchar_buffered(char c) { ring_buffer_put(_uart_a0_tx_ringbuffer_id, &c); event_signal(_uart_a0_tx_start_ev); }
/** * Move player in the given direction. * * This routine should only be called when energy has been expended. * * Note that this routine handles monsters in the destination grid, * and also handles attempting to move into walls/doors/rubble/etc. */ void move_player(int dir, bool disarm) { int y = player->py + ddy[dir]; int x = player->px + ddx[dir]; int m_idx = cave->squares[y][x].mon; struct monster *mon = cave_monster(cave, m_idx); bool alterable = (square_isknowntrap(cave, y, x) || square_iscloseddoor(cave, y, x)); /* Attack monsters, alter traps/doors on movement, hit obstacles or move */ if (m_idx > 0) { /* Mimics surprise the player */ if (is_mimicking(mon)) { become_aware(mon); /* Mimic wakes up */ mon_clear_timed(mon, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE, false); } else { py_attack(y, x); } } else if (disarm && square_isknown(cave, y, x) && alterable) { /* Auto-repeat if not already repeating */ if (cmd_get_nrepeats() == 0) cmd_set_repeat(99); do_cmd_alter_aux(dir); } else if (player->upkeep->running && square_isknowntrap(cave, y, x)) { /* Stop running before known traps */ disturb(player, 0); } else if (!square_ispassable(cave, y, x)) { disturb(player, 0); /* Notice unknown obstacles, mention known obstacles */ if (!square_isknown(cave, y, x)) { if (square_isrubble(cave, y, x)) { msgt(MSG_HITWALL, "You feel a pile of rubble blocking your way."); square_memorize(cave, y, x); square_light_spot(cave, y, x); } else if (square_iscloseddoor(cave, y, x)) { msgt(MSG_HITWALL, "You feel a door blocking your way."); square_memorize(cave, y, x); square_light_spot(cave, y, x); } else { msgt(MSG_HITWALL, "You feel a wall blocking your way."); square_memorize(cave, y, x); square_light_spot(cave, y, x); } } else { if (square_isrubble(cave, y, x)) msgt(MSG_HITWALL, "There is a pile of rubble blocking your way."); else if (square_iscloseddoor(cave, y, x)) msgt(MSG_HITWALL, "There is a door blocking your way."); else msgt(MSG_HITWALL, "There is a wall blocking your way."); } } else { /* Move player */ monster_swap(player->py, player->px, y, x); /* Handle store doors, or notice objects */ if (square_isshop(cave, y, x)) { disturb(player, 0); event_signal(EVENT_ENTER_STORE); event_remove_handler_type(EVENT_ENTER_STORE); event_signal(EVENT_USE_STORE); event_remove_handler_type(EVENT_USE_STORE); event_signal(EVENT_LEAVE_STORE); event_remove_handler_type(EVENT_LEAVE_STORE); } else { square_know_pile(cave, y, x); cmdq_push(CMD_AUTOPICKUP); } /* Discover invisible traps, set off visible ones */ if (square_issecrettrap(cave, y, x)) { disturb(player, 0); hit_trap(y, x); } else if (square_isknowntrap(cave, y, x)) { disturb(player, 0); hit_trap(y, x); } /* Update view and search */ update_view(cave, player); search(); } player->upkeep->running_firststep = false; }
/* * Handle "target" and "look". * * Note that this code can be called from "get_aim_dir()". * * Currently, when "flag" is true, that is, when * "interesting" grids are being used, and a directional key is used, we * only scroll by a single panel, in the direction requested, and check * for any interesting grids on that panel. The "correct" solution would * actually involve scanning a larger set of grids, including ones in * panels which are adjacent to the one currently scanned, but this is * overkill for this function. XXX XXX * * Hack -- targetting/observing an "outer border grid" may induce * problems, so this is not currently allowed. * * The player can use the direction keys to move among "interesting" * grids in a heuristic manner, or the "space", "+", and "-" keys to * move through the "interesting" grids in a sequential manner, or * can enter "location" mode, and use the direction keys to move one * grid at a time in any direction. The "t" (set target) command will * only target a monster (as opposed to a location) if the monster is * target_able and the "interesting" mode is being used. * * The current grid is described using the "look" method above, and * a new command may be entered at any time, but note that if the * "TARGET_LOOK" bit flag is set (or if we are in "location" mode, * where "space" has no obvious meaning) then "space" will scan * through the description of the current grid until done, instead * of immediately jumping to the next "interesting" grid. This * allows the "target" command to retain its old semantics. * * The "*", "+", and "-" keys may always be used to jump immediately * to the next (or previous) interesting grid, in the proper mode. * * The "return" key may always be used to scan through a complete * grid description (forever). * * This command will cancel any old target, even if used from * inside the "look" command. * * 'mode' is one of TARGET_LOOK or TARGET_KILL. * 'x' and 'y' are the initial position of the target to be highlighted, * or -1 if no location is specified. * Returns TRUE if a target has been successfully set, FALSE otherwise. */ bool target_set_interactive(int mode, int x, int y) { int py = p_ptr->py; int px = p_ptr->px; int i, d, m, t, bd; int wid, hgt, help_prompt_loc; bool done = FALSE; bool flag = TRUE; bool help = FALSE; bool list_floor_objects = auto_display_lists; u16b path_n; u16b path_g[PATH_SIZE]; u16b path_gx[PATH_SIZE]; ui_event_data query; char info[80]; /* These are used for displaying the path to the target */ char path_char[MAX_RANGE]; byte path_attr[MAX_RANGE]; /* If we haven't been given an initial location, start on the player. */ if (x == -1 || y == -1) { x = p_ptr->px; y = p_ptr->py; } /* If we /have/ been given an initial location, make sure we honour it by going into "free targeting" mode. */ else { flag = FALSE; } /* Cancel target */ target_set_monster(0); /* make some buttons */ button_backup_all(); button_kill_all(); button_add("[ESCAPE]", ESCAPE); button_add("[NEXT]", '+'); button_add("[PREV]", '-'); button_add("[PLAYER]", 'p'); button_add("[PATHFIND]", 'g'); button_add("[TARGET]", 't'); /* health_track(0); */ /* All grids are selectable */ if (mode & (TARGET_GRID)) { /* Disable other modes */ mode &= ~(TARGET_LOOK | TARGET_KILL | TARGET_TRAP); /* Disable interesting grids */ flag = FALSE; } /* Calculate the window location for the help prompt */ Term_get_size(&wid, &hgt); help_prompt_loc = hgt - (mouse_buttons ? 2 : 1); /* Display the help prompt */ prt("'?' - help", help_prompt_loc, 0); /* Prepare the "temp" array */ target_set_interactive_prepare(mode); /* Start near the player */ m = 0; /* Interact */ while (!done) { button_kill('l'); button_kill('?'); if (list_floor_objects) { button_add("[HIDE_OBJLIST]", 'l'); } else button_add("[SHOW_OBJLIST]", 'l'); if (help) { button_add("[HIDE_HELP]", '?'); } else button_add("[SHOW_HELP]",'?'); /* Interesting grids */ if (flag && temp_n) { bool path_drawn = FALSE; int yy, xx; y = temp_y[m]; x = temp_x[m]; button_add("[SCAN]",'o'); /* Update help */ if (help) { bool good_target = ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])); target_display_help(good_target, !(flag && temp_n)); } /* Dummy pointers to send to project_path */ yy = y; xx = x; /* Allow targets for monsters....or traps, if applicable */ if (((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])) || ((mode & (TARGET_TRAP)) && target_able_trap(y, x))) { strcpy(info, "q,t,r,l,p,o,+,-,<dir>"); } /* Dis-allow target */ else { strcpy(info, "q,p,l,o,+,-,<dir>"); } /* Adjust panel if needed */ if (adjust_panel(y, x)) { /* Handle stuff */ handle_stuff(); } /* Find the path. */ path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU); /* Draw the path in "target" mode. If there is one */ if ((mode & (TARGET_KILL)) && (cave_info[y][x] & (CAVE_FIRE))) { path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px, y, x); } event_signal(EVENT_MOUSEBUTTONS); /* Describe and Prompt */ query = target_set_interactive_aux(y, x, mode, info, list_floor_objects); /* Remove the path */ if (path_drawn) load_path(path_n, path_g, path_char, path_attr); /* Cancel tracking */ /* health_track(0); */ /* Assume no "direction" */ d = 0; /* Analyze */ switch (query.key) { case ESCAPE: case 'q': { done = TRUE; break; } case ' ': case '*': case '+': { if (++m == temp_n) m = 0; break; } case '-': { if (m-- == 0) m = temp_n - 1; break; } case 'p': { /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); y = py; x = px; } case 'o': { flag = FALSE; break; } case 'm': { break; } /* If we click, move the target location to the click and switch to "free targetting" mode by unsetting 'flag'. This means we get some info about wherever we've picked. */ case DEFINED_XFF: { x = KEY_GRID_X(query); y = KEY_GRID_Y(query); flag = FALSE; break; } case 't': case '5': case '0': case '.': { int m_idx = cave_m_idx[y][x]; if ((m_idx > 0) && target_able(m_idx)) { health_track(m_idx); target_set_monster(m_idx); done = TRUE; } else if ((mode & (TARGET_TRAP)) && target_able_trap(y, x)) { target_set_location(y, x); done = TRUE; } else if (mode & (TARGET_PROBE)) { target_set_location(y, x); done = TRUE; } else { bell("Illegal target!"); } break; } case 'g': { cmd_insert(CMD_PATHFIND, y, x); done = TRUE; break; } case 'l': { list_floor_objects = (!list_floor_objects); } case '?': { help = !help; /* Redraw main window */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); handle_stuff(); if (!help) prt("'?' - help", help_prompt_loc, 0); break; } default: { /* Extract direction */ d = target_dir(query.key); /* Oops */ if (!d) bell("Illegal command for target mode!"); break; } } /* Hack -- move around */ if (d) { int old_y = temp_y[m]; int old_x = temp_x[m]; /* Find a new monster */ i = target_pick(old_y, old_x, ddy[d], ddx[d]); /* Scroll to find interesting grid */ if (i < 0) { int old_wy = Term->offset_y; int old_wx = Term->offset_x; /* Change if legal */ if (change_panel(d)) { /* Recalculate interesting grids */ target_set_interactive_prepare(mode); /* Find a new monster */ i = target_pick(old_y, old_x, ddy[d], ddx[d]); /* Restore panel if needed */ if ((i < 0) && modify_panel(Term, old_wy, old_wx)) { /* Recalculate interesting grids */ target_set_interactive_prepare(mode); } /* Handle stuff */ handle_stuff(); } } /* Use interesting grid if found */ if (i >= 0) m = i; } } /* Arbitrary grids */ else { bool path_drawn = FALSE; /* Dummy pointers to send to project_path */ int yy = y; int xx = x; /* Don't need this button any more */ button_kill('o'); /* Update help */ if (help) { bool good_target = ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])); target_display_help(good_target, !(flag && temp_n)); } /* Default prompt */ if (!(mode & (TARGET_GRID))) { strcpy(info, "q,t,l,p,m,+,-,<dir>"); } /* Disable monster selection */ else { strcpy(info, "q,t,l.p,+,-,<dir>"); } /* Find the path. */ path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU); /* Draw the path in "target" mode. If there is one */ if ((mode & (TARGET_KILL)) && (cave_info[y][x] & (CAVE_FIRE))) { /* Save target info */ path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px, y, x); } event_signal(EVENT_MOUSEBUTTONS); /* Describe and Prompt (enable "TARGET_LOOK") */ query = target_set_interactive_aux(y, x, (mode | TARGET_LOOK), info, list_floor_objects); /* Remove the path */ if (path_drawn) load_path(path_n, path_g, path_char, path_attr); /* Cancel tracking */ /* health_track(0); */ /* Assume no direction */ d = 0; /* Analyze the keypress */ switch (query.key) { case ESCAPE: case 'q': { done = TRUE; break; } case ' ': case '*': case '+': case '-': { break; } case 'p': { /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); y = py; x = px; } case 'o': { break; } case 'm': { /* Monster selection is disabled */ if (mode & (TARGET_GRID)) break; flag = TRUE; m = 0; bd = 999; /* Pick a nearby monster */ for (i = 0; i < temp_n; i++) { t = distance(y, x, temp_y[i], temp_x[i]); /* Pick closest */ if (t < bd) { m = i; bd = t; } } /* Nothing interesting */ if (bd == 999) flag = FALSE; break; } case '\xff': { /* We only target if we click somewhere where the cursor is already (i.e. a double-click without a time limit) */ if (KEY_GRID_X(query) == x && KEY_GRID_Y(query) == y) { /* Make an attempt to target the monster on the given square rather than the square itself (it seems this is the more likely intention of clicking on a monster). */ int m_idx = cave_m_idx[y][x]; if ((m_idx > 0) && target_able(m_idx)) { health_track(m_idx); target_set_monster(m_idx); } else { /* There is no monster, or it isn't targettable, so target the location instead. */ target_set_location(y, x); } done = TRUE; } else { /* Just move the cursor for now - another click will target. */ x = KEY_GRID_X(query); y = KEY_GRID_Y(query); } break; } case 't': case '5': case '0': case '.': { target_set_location(y, x); done = TRUE; break; } case 'g': { cmd_insert(CMD_PATHFIND, y, x); done = TRUE; break; } case 'l': { list_floor_objects = (!list_floor_objects); } case '?': { help = !help; /* Redraw main window */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); handle_stuff(); if (!help) prt("'?' - help.", help_prompt_loc, 0); break; } default: { /* Extract a direction */ d = target_dir(query.key); /* Oops */ if (!d) bell("Illegal command for target mode!"); break; } } /* Handle "direction" */ if (d) { int dungeon_hgt = p_ptr->cur_map_hgt; int dungeon_wid = p_ptr->cur_map_wid; /* Move */ x += ddx[d]; y += ddy[d]; /* Slide into legality */ if (x >= dungeon_wid - 1) x--; else if (x <= 0) x++; /* Slide into legality */ if (y >= dungeon_hgt - 1) y--; else if (y <= 0) y++; /* Adjust panel if needed */ if (adjust_panel(y, x)) { /* Handle stuff */ handle_stuff(); /* Recalculate interesting grids */ target_set_interactive_prepare(mode); } } } } /* Forget */ temp_n = 0; /* Redraw as necessary */ if (help) { p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); } else { prt("", 0, 0); prt("", help_prompt_loc, 0); p_ptr->redraw |= (PR_DEPTH | PR_STATUS); } /* Recenter around player */ verify_panel(); /* Restore buttons */ button_restore(); /* Handle stuff */ handle_stuff(); /* Failure to set target */ if (!p_ptr->target_set) return (FALSE); /* Success */ return (TRUE); }
/** * @brief function that handles certain signals being delivered to the scheduler * * This function is called every time the event loop attempts to take something * from the event queue. It will also get called once a second regardless of if * a new event has been queued. * * This function checks the sigmask variable to check what signals have been * received since the last time it was called. The sigmask variable should * always be accessed atomically since it is accessed by the event loop thread * as well as the signal handlers. */ void scheduler_signal(scheduler_t* scheduler) { // the last time an update was run static time_t last_update = 0; // copy of the mask guint mask; /* this will get sigmask and set it to 0 */ #if __GNUC__ mask = __sync_fetch_and_and(&sigmask, 0); #else mask = sigmask; sigmask = 0; #endif /* initialize last_update */ if(last_update == 0) last_update = time(NULL); /* signal: SIGCHLD * * A SIGCHLD has been received since the last time signal_scheduler() was * called. Get all agents that have finished since last this happened and * create an event for each. */ if(mask & MASK_SIGCHLD) { pid_t n; // the next pid that has died pid_t* pass; int status; // status returned by waitpit() /* get all of the dead children's pids */ while((n = waitpid(-1, &status, WNOHANG)) > 0) { V_SCHED("SIGNALS: received sigchld for pid %d\n", n); pass = g_new0(pid_t, 2); pass[0] = n; pass[1] = status; event_signal(agent_death_event, pass); } } /* signal: SIGTERM * * A SIGTERM has been received. simply set the closing flag to 1 so that the * scheduler will gracefully shutdown as all the agents finish running. */ if(mask & MASK_SIGTERM) { V_SCHED("SIGNALS: Scheduler received terminate signal, shutting down gracefully\n"); event_signal(scheduler_close_event, (void*)0); } /* signal: SIGQUIT * * A SIGQUIT has been received. Queue a scheduler_close_event so that the * scheduler will imediately stop running. This will cause all the agents to * be forcefully killed. */ if(mask & MASK_SIGQUIT) { V_SCHED("SIGNALS: Scheduler received quit signal, shutting down scheduler\n"); event_signal(scheduler_close_event, (void*)1); } /* signal: SIGHUP * * A SIGHUP has been received. reload the configuration files for the * scheduler. This will run here instead of being queued as an event. */ if(mask & MASK_SIGHUP) { V_SCHED("SIGNALS: Scheduler received SGIHUP, reloading configuration data\n"); scheduler_config_event(scheduler, NULL); } /* Finish by checking if an agent update needs to be performed. * * Every CONF_agent_update_interval, the agents and database should be * updated. The agents need to be updated to check for dead and unresponsive * agents. The database is updated to make sure that a new job hasn't been * scheduled without the scheduler being informed. */ if((time(NULL) - last_update) > CONF_agent_update_interval ) { V_SPECIAL("SIGNALS: Performing agent and database update\n"); event_signal(agent_update_event, NULL); event_signal(database_update_event, NULL); last_update = time(NULL); } }
/** * Close up the current game (player may or may not be dead) * * Note that the savefile is not saved until the tombstone is * actually displayed and the player has a chance to examine * the inventory and such. This allows cheating if the game * is equipped with a "quit without save" method. XXX XXX XXX */ void close_game(void) { /* Tell the UI we're done with the world */ event_signal(EVENT_LEAVE_WORLD); /* Handle stuff */ handle_stuff(player); /* Flush the messages */ event_signal(EVENT_MESSAGE_FLUSH); /* Flush the input */ event_signal(EVENT_INPUT_FLUSH); /* No suspending now */ signals_ignore_tstp(); /* Hack -- Increase "icky" depth */ screen_save_depth++; /* Save monster memory to user directory */ if (!lore_save("lore.txt")) { msg("lore save failed!"); event_signal(EVENT_MESSAGE_FLUSH); } /* Handle death or life */ if (player->is_dead) { death_knowledge(); death_screen(); /* Save dead player */ if (!savefile_save(savefile)) { msg("death save failed!"); event_signal(EVENT_MESSAGE_FLUSH); } } else { /* Save the game */ save_game(); if (Term->mapped_flag) { struct keypress ch; prt("Press Return (or Escape).", 0, 40); ch = inkey(); if (ch.code != ESCAPE) predict_score(); } } /* Wipe the monster list */ wipe_mon_list(cave, player); /* Hack -- Decrease "icky" depth */ screen_save_depth--; /* Tell the UI we're done with the game state */ event_signal(EVENT_LEAVE_GAME); /* Allow suspending now */ signals_handle_tstp(); }
static void parse_status_line (Call *c, char **bufp, size_t *buf_lenp) { char *buf, *buf_start = *bufp; u_int major, minor, status; Conn *s = c->conn; Any_Type arg; s->is_chunked = 0; /* default to "infinite" content length: */ s->content_length = ~(size_t) 0; if (!get_line (c, bufp, buf_lenp)) return; buf = c->conn->line.iov_base; if (sscanf (buf, "HTTP/%u.%u %u ", &major, &minor, &status) == 3) { c->reply.version = 0x10000*major + minor; c->reply.status = status; } else { c->reply.version = 0x10000; /* default to 1.0 */ c->reply.status = 599; if (c->reply.status == 599) fprintf (stderr, "%s.parse_status_line: invalid status line `%s'!!\n", prog_name, buf); } if (DBG > 0) fprintf (stderr, "parse_status_line.%lu: reply is HTTP/%u.%u, status = %d\n", c->id, c->reply.version / 0x10000, c->reply.version & 0xffff, c->reply.status); /* Determine whether we should be expecting a message body. HEAD never includes an entity. For other methods, things depend on the status code. */ if (strcmp ((char *) c->req.iov[IE_METHOD].iov_base, "HEAD") == 0) s->has_body = 0; else { s->has_body = 1; switch (status / 100) { case 1: /* informational */ s->has_body = 0; if (status == 100) { arg.l = c->reply.status; event_signal (EV_CALL_RECV_START, (Object *) c, arg); s->state = S_REPLY_CONTINUE; goto done; } break; case 2: /* success */ case 3: /* redirection */ switch (status) { case 204: /* No Content */ case 205: /* Reset Content */ case 304: /* Not Modified */ s->has_body = 0; break; } break; case 4: /* client errors */ case 5: /* server errors */ break; default: fprintf (stderr, "%s.parse_status_line: bad status %u\n", prog_name, status); break; } } arg.l = c->reply.status; event_signal (EV_CALL_RECV_START, (Object *) c, arg); if (s->state >= S_CLOSING) return; s->state = S_REPLY_HEADER; done: c->reply.header_bytes += *bufp - buf_start; s->line.iov_len = 0; }