/** * @brief ggs_saio_delay * * Parse a "saio" from a GGS input text. * When Saio is building is book, it tells when it will be available again. * Edax will automatically re-start asking him to play again at the right moment. * * @param text GGS input text. * @param delay Time delay (in ms). * @return 'true' if the text is a valid saio delay. */ static bool ggs_saio_delay(Text *text, long long *delay) { const char *s = strstr(text->line[0], "Sorry, i will accept new games in"); if (s && strlen(s) > 35) { errno = 0; *delay = string_to_int(s + 34, 300) * 1000 + real_clock(); return (errno == 0); } return false; }
/** * @brief ggs_client_refresh * * Periodically send a message to the GGS server. * This is a workaround to avoid spurious deconnection from GGS. * * @param client GGS client. */ static void ggs_client_refresh(GGSClient *client) { /* send "tell /os continue" every minute */ if (real_clock() - client->last_refresh > 60000) { // 60 sec. if (client->is_playing) ggs_client_send(client, "tell /os open 0\n" ); else ggs_client_send(client, "tell /os open %d\n", options.ggs_open); ggs_client_send(client, "tell /os continue\n"); client->last_refresh = real_clock(); } /* check loop */ if (client->loop->delay != 0 && real_clock() - client->loop->delay > 0) { client->loop->delay = 0; ggs_client_send(client, "%s\n", client->loop->cmd); } /* check once */ if (client->once->cmd && client->once->delay != 0 && real_clock() - client->once->delay > 0) { client->once->delay = 0; ggs_client_send(client, "%s\n", client->once->cmd); } }
/** * @brief ui_login * * Connect to GGS. * * @param ui User Interface. */ static void ui_login(UI *ui) { GGSClient *client = ui->ggs; /* sanity check */ if (options.ggs_host == NULL) fatal_error("Unknown GGS host\n"); if (options.ggs_port == NULL) fatal_error("Unknown GGS port\n"); if (options.ggs_login == NULL) fatal_error("Unknown GGS login\n"); if (options.ggs_password == NULL) fatal_error("Unknown GGS password\n"); if (strlen(options.ggs_login) > 8) fatal_error("Bad GGS login %s (too much characters)\n", options.ggs_login); printf("Connecting to GGS...\n"); memset(client, 0, sizeof (GGSClient)); client->me = options.ggs_login; client->loop->cmd = NULL; client->loop->i = 0; client->loop->delay = 0; client->once->cmd = NULL; client->once->delay = 0; client->last_refresh = real_clock(); ggs_event_init(&client->event); }
/** * @brief ui_loop_ggs * * GGS main loop. Here the input from both the user and * GGS server is interpreted. * * @param ui User Interface. */ void ui_loop_ggs(UI *ui) { char *cmd = NULL, *param = NULL; Text text[1]; GGSClient *client = ui->ggs; ui->mode = 3; text_init(text); for (;;) { relax(10); /* look for a user event */ if (ui_event_peek(ui, &cmd, ¶m)) { /* stop the search */ if (strcmp(cmd, "stop") == 0) { if (ui->play[0].state == IS_THINKING) play_stop(ui->play); else if (ui->play[1].state == IS_THINKING) play_stop(ui->play + 1); /* repeat a cmd <n> times */ } else if (strcmp(cmd, "loop") == 0) { free(client->loop->cmd); errno = 0; client->loop->cmd = string_duplicate(parse_int(param, &client->loop->i)); if (errno) client->loop->i = 100; if (client->loop->i > 0) { info("<loop %d>\n", client->loop->i); --client->loop->i; ggs_client_send(client, "%s\n", client->loop->cmd); } /* exit from ggs */ } else if (strcmp(cmd, "quit") == 0 || strcmp(cmd, "q") == 0) { ggs_client_send(client, "tell .%s Bye bye!\n", client->me); ggs_client_send(client, "quit\n"); free(cmd); free(param); return; /* send the command to ggs */ } else { ggs_client_send(client, "%s %s\n", cmd, param); } } /* stay on line... */ ggs_client_refresh(client); /* look for a ggs event */ if (!ggs_event_peek(&client->event, text)) { continue; } text_print(text, stdout); if (ggs_log->f) text_print(text, ggs_log->f); /* login */ if (ggs_login(text)) { ggs_client_send(client, "%s\n", options.ggs_login); /* password */ } else if (ggs_password(text)) { ggs_client_send(client, "%s\n", options.ggs_password); ggs_client_send(client, "vt100 -\n"); ggs_client_send(client, "bell -t -tc -tg -n -nc -ng -ni -nn\n"); ggs_client_send(client, "verbose -news -faq -help -ack\n"); ggs_client_send(client, "chann %%\n"); ggs_client_send(client, "chann + .chat\n"); ggs_client_send(client, "chann + .%s\n", client->me); ggs_client_send(client, "tell .%s Hello!\n", client->me); /* os on */ } else if (ggs_os_on(text)) { printf("[received GGS_OS_ON]\n"); ggs_client_send(client, "tell /os trust +\n" ); ggs_client_send(client, "tell /os rated +\n" ); ggs_client_send(client, "tell /os request +\n" ); ggs_client_send(client, "tell /os client -\n" ); ggs_client_send(client, "tell /os open %d\n", options.ggs_open); ggs_client_send(client, "mso\n" ); /* os off */ } else if (ggs_os_off(text)) { printf("[received GGS_OS_OFF]\n"); /* match on */ } else if (ggs_match_on(client->match_on, text)) { if (ggs_has_player(client->match_on->player, client->me)) { printf("[received GGS_MATCH_ON]\n"); client->is_playing = true; ggs_client_send(client, "tell /os open 0\n" ); } else { printf("[received GGS_WATCH_ON]\n"); } /* match off */ } else if (ggs_match_off(client->match_off, text)) { if (ggs_has_player(client->match_off->player, client->me)) { printf("[received GGS_MATCH_OFF]\n"); if (!client->match_on->match_type->is_rand) { if (client->match_on->match_type->is_synchro) { printf("[store match #1]\n"); play_store(ui->play); printf("[store match #2]\n"); play_store(ui->play + 1); } else { printf("[store match]\n"); play_store(ui->play); } if (ui->book->need_saving) { book_save(ui->book, options.book_file); ui->book->need_saving = false; } } client->is_playing = false; ggs_client_send(client, "tell /os open %d\n", options.ggs_open); if (client->loop->i > 0) { info("<loop %d>\n", client->loop->i); --client->loop->i; client->loop->delay = 10000 + real_clock(); // wait 10 sec. } } else { printf("[received GGS_WATCH_OFF]\n"); } /* board join/update */ } else if (ggs_board(client->board, text)) { if (ggs_has_player(client->board->player, client->me)) { if (client->board->is_join) ui_ggs_join(ui); else ui_ggs_update(ui); } else { printf("[received GGS_WATCH_BOARD]\n"); } /* request */ } else if (ggs_request(client->request, text)) { printf("[received GGS_REQUEST]\n"); /* admin on */ } else if (ggs_admin(client->admin, text)) { printf("[received GGS_ADMIN_CMD]\n"); ggs_client_send(client, client->admin->command); ggs_client_send(client, "\ntell %s command processed\n", client->admin->name); /* To request Saio a game later */ } else if (ggs_saio_delay(text, &client->once->delay)) { printf("[received GGS_SAIO_DELAY]\n"); free(client->once->cmd); client->once->cmd = NULL; if (cmd != NULL && param != NULL) { if (strcmp(cmd, "loop") == 0) { client->once->cmd = string_duplicate(client->loop->cmd); } else { client->once->cmd = (char*) malloc(strlen(cmd) + strlen(param) + 3); sprintf(client->once->cmd, "%s %s\n", cmd, param); } printf("[received GGS_SAIO_DELAY, retry request in %.1f s]\n", 0.001 * (client->once->delay - real_clock())); } else { client->once->delay = 0; } /* READY */ } else if (ggs_ready(text)) { /* ALERT */ } else if (ggs_alert(text)) { printf("[received ALERT]\n"); /* Other messages */ } else { } text_free(text); } }
void PostRendering_DOF(cImage *image, double deep, double neutral) { isPostRendering = true; int width = image->GetWidth(); int height = image->GetHeight(); sRGB16 *temp_image = new sRGB16[width * height]; unsigned short *temp_alpha = new unsigned short[width * height]; sSortZ<float> *temp_sort = new sSortZ<float>[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int ptr = x + y * width; temp_image[ptr] = image->GetPixelImage16(x, y); temp_alpha[ptr] = image->GetPixelAlpha(x, y); temp_sort[ptr].z = image->GetPixelZBuffer(x, y); temp_sort[ptr].i = ptr; } } if (!noGUI && image->IsPreview()) { gtk_progress_bar_set_text(GTK_PROGRESS_BAR(Interface.progressBar), "Rendering Depth Of Field effect. Sorting zBuffer"); while (gtk_events_pending()) gtk_main_iteration(); } QuickSortZBuffer(temp_sort, 1, height * width - 1); if (!noGUI && image->IsPreview()) { gtk_progress_bar_set_text(GTK_PROGRESS_BAR(Interface.progressBar), "Rendering Depth Of Field effect. Randomizing zBuffer"); while (gtk_events_pending()) gtk_main_iteration(); } //Randomize Z-buffer int imgSize = height*width; for(int i=imgSize-1; i>=0; i--) { sSortZ<float> temp; temp = temp_sort[i]; double z1 = temp.z; double size1 = (z1 - neutral) / z1 * deep; int randomStep = i; bool done = false; int ii; do { ii = i - Random(randomStep); if (ii <= 0) ii = 0; sSortZ<float> temp2 = temp_sort[ii]; double z2 = temp2.z; double size2 = (z2 - neutral) / z2 * deep; if(size1 == 0 && size2 ==0) done = true; if (size1 * size2 > 0) { double sizeCompare; if (size1 > 0) { sizeCompare = size2 / size1; } else { sizeCompare = size1 / size2; } if (sizeCompare > 0.7) { done = true; } else { done = false; } } else { done = false; } randomStep = randomStep * 0.7 - 1; if(randomStep <= 0) done = true; } while(!done); temp_sort[i] = temp_sort[ii]; temp_sort[ii] = temp; } if (!noGUI && image->IsPreview()) { gtk_progress_bar_set_text(GTK_PROGRESS_BAR(Interface.progressBar), "Rendering Depth Of Field effect. Done 0%"); while (gtk_events_pending()) gtk_main_iteration(); } double last_time = real_clock(); int refreshCount = 0; for (int i = 0; i < height * width; i++) { int ii = temp_sort[height * width - i - 1].i; int x = ii % width; int y = ii / width; double z = image->GetPixelZBuffer(x, y); double blur = fabs((double) z - neutral) / z * deep; if (blur > 100) blur = 100.0; int size = blur; sRGB16 center = temp_image[x + y * width]; unsigned short center_alpha = temp_alpha[x + y * width]; double factor = blur * blur * sqrt(blur)* M_PI/3.0; for (int yy = y - size; yy <= y + size; yy++) { for (int xx = x - size; xx <= x + size; xx++) { if (xx >= 0 && xx < width && yy >= 0 && yy < height) { int dx = xx - x; int dy = yy - y; double r = sqrt((float)dx * dx + dy * dy); double op = (blur - r) / factor; if (op > 1.0) op = 1.0; if (op < 0.0) op = 0.0; if (op > 0.0) { double opN = 1.0 - op; sRGB16 old = image->GetPixelImage16(xx, yy); unsigned short old_alpha = image->GetPixelAlpha(xx, yy); sRGB16 pixel; pixel.R = old.R * opN + center.R * op; pixel.G = old.G * opN + center.G * op; pixel.B = old.B * opN + center.B * op; unsigned short alpha = old_alpha * opN + center_alpha * op; image->PutPixelImage16(xx, yy, pixel); image->PutPixelAlpha(xx, yy, alpha); } } } } double time = real_clock(); if (time - last_time > 0.1 && !noGUI && image->IsPreview()) { char progressText[1000]; last_time = real_clock(); double percent_done = (double) i / (height * width) * 100.0; sprintf(progressText, "Rendering Depth Of Field effect. Done %.2f%%", percent_done); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(Interface.progressBar), progressText); if(refreshCount > 600) { //image->CompileImage(); image->ConvertTo8bit(); image->UpdatePreview(); image->RedrawInWidget(renderWindow.drawingArea); refreshCount = 0; } refreshCount++; while (gtk_events_pending()) gtk_main_iteration(); } if (i % 1000 == 0) { double percentDone = (double)i/(width*height)*100.0; printf("Rendering Depth Of Field efect. Done %.2f%% \r", percentDone); fflush(stdout); } if (!isPostRendering) break; } if (!noGUI && image->IsPreview()) { gtk_progress_bar_set_text(GTK_PROGRESS_BAR(Interface.progressBar), "Rendering Depth Of Field effect. Done 100%"); while (gtk_events_pending()) gtk_main_iteration(); } printf("Rendering Depth Of Field efect. Done 100%% \n"); isPostRendering = false; delete[] temp_image; delete[] temp_alpha; delete[] temp_sort; }