int time_test() { int passed = 1; int32_t then, now, diff; then = platform_get_ticks(); platform_sleep(5); now = platform_get_ticks(); diff = now - then; if(diff < 4 || diff > 20) passed = 0; then = platform_get_ticks(); diff = then - now; if(diff < 0 || diff > 5) passed = 0; platform_sleep(50); now = platform_get_ticks(); diff = now - then; if(diff < 40 || diff > 70) passed = 0; return passed; }
void chat_history_add(const char* src) { size_t bufferSize = strlen(src) + 64; utf8* buffer = (utf8*)calloc(1, bufferSize); // Find the start of the text (after format codes) const char* ch = src; const char* nextCh; uint32_t codepoint; while ((codepoint = utf8_get_next(ch, &nextCh)) != 0) { if (!utf8_is_format_code(codepoint)) { break; } ch = nextCh; } const char* srcText = ch; // Copy format codes to buffer std::memcpy(buffer, src, std::min(bufferSize, (size_t)(srcText - src))); // Prepend a timestamp time_t timer; time(&timer); struct tm* tmInfo = localtime(&timer); strcatftime(buffer, bufferSize, "[%H:%M] ", tmInfo); safe_strcat(buffer, srcText, bufferSize); // Add to history list int32_t index = _chatHistoryIndex % CHAT_HISTORY_SIZE; std::fill_n(_chatHistory[index], CHAT_INPUT_SIZE, 0x00); std::memcpy(_chatHistory[index], buffer, std::min<size_t>(strlen(buffer), CHAT_INPUT_SIZE - 1)); _chatHistoryTime[index] = platform_get_ticks(); _chatHistoryIndex++; // Log to file (src only as logging does its own timestamp) network_append_chat_log(src); free(buffer); Mixer_Play_Effect(SOUND_NEWS_ITEM, 0, MIXER_VOLUME_MAX, 0.5f, 1.5f, true); }
void chat_draw(rct_drawpixelinfo* dpi, uint8_t chatBackgroundColor) { if (!chat_available()) { gChatOpen = false; return; } _chatLeft = 10; _chatRight = std::min((context_get_width() - 10), CHAT_MAX_WINDOW_WIDTH); _chatWidth = _chatRight - _chatLeft; _chatBottom = context_get_height() - 45; _chatTop = _chatBottom - 10; char lineBuffer[CHAT_INPUT_SIZE + 10]; char* lineCh = lineBuffer; char* inputLine = _chatCurrentLine; int32_t inputLineHeight = 10; // Draw chat window if (gChatOpen) { inputLineHeight = chat_string_wrapped_get_height((void*)&inputLine, _chatWidth - 10); _chatTop -= inputLineHeight; for (int32_t i = 0; i < CHAT_HISTORY_SIZE; i++) { if (strlen(chat_history_get(i)) == 0) { continue; } safe_strcpy(lineBuffer, chat_history_get(i), sizeof(lineBuffer)); int32_t lineHeight = chat_string_wrapped_get_height((void*)&lineCh, _chatWidth - 10); _chatTop -= (lineHeight + 5); } _chatHeight = _chatBottom - _chatTop; if (_chatTop < 50) { _chatTop = 50; } else if (_chatHeight < 150) { // Min height _chatTop = _chatBottom - 150; _chatHeight = 150; } gfx_set_dirty_blocks(_chatLeft, _chatTop - 5, _chatRight, _chatBottom + 5); // Background area + Textbox gfx_filter_rect(dpi, _chatLeft, _chatTop - 5, _chatRight, _chatBottom + 5, PALETTE_51); // Opaque gray background gfx_fill_rect_inset( dpi, _chatLeft, _chatTop - 5, _chatRight, _chatBottom + 5, chatBackgroundColor, INSET_RECT_FLAG_FILL_NONE); gfx_fill_rect_inset( dpi, _chatLeft + 1, _chatTop - 4, _chatRight - 1, _chatBottom - inputLineHeight - 6, chatBackgroundColor, INSET_RECT_FLAG_BORDER_INSET); gfx_fill_rect_inset( dpi, _chatLeft + 1, _chatBottom - inputLineHeight - 5, _chatRight - 1, _chatBottom + 4, chatBackgroundColor, INSET_RECT_FLAG_BORDER_INSET); // Textbox } int32_t x = _chatLeft + 5; int32_t y = _chatBottom - inputLineHeight - 20; int32_t stringHeight = 0; // Draw chat history for (int32_t i = 0; i < CHAT_HISTORY_SIZE; i++, y -= stringHeight) { uint32_t expireTime = chat_history_get_time(i) + 10000; if (!gChatOpen && platform_get_ticks() > expireTime) { break; } safe_strcpy(lineBuffer, chat_history_get(i), sizeof(lineBuffer)); stringHeight = chat_history_draw_string(dpi, (void*)&lineCh, x, y, _chatWidth - 10) + 5; gfx_set_dirty_blocks(x, y - stringHeight, x + _chatWidth, y + 20); if ((y - stringHeight) < 50) { break; } } // Draw current chat input if (gChatOpen) { lineCh = utf8_write_codepoint(lineCh, FORMAT_OUTLINE); lineCh = utf8_write_codepoint(lineCh, FORMAT_CELADON); safe_strcpy(lineCh, _chatCurrentLine, sizeof(_chatCurrentLine)); y = _chatBottom - inputLineHeight - 5; lineCh = lineBuffer; inputLineHeight = gfx_draw_string_left_wrapped( dpi, (void*)&lineCh, x, y + 3, _chatWidth - 10, STR_STRING, TEXT_COLOUR_255); gfx_set_dirty_blocks(x, y, x + _chatWidth, y + inputLineHeight + 15); // TODO: Show caret if the input text has multiple lines if (_chatCaretTicks < 15 && gfx_get_string_width(lineBuffer) < (_chatWidth - 10)) { std::memcpy(lineBuffer, _chatCurrentLine, _chatTextInputSession->SelectionStart); lineBuffer[_chatTextInputSession->SelectionStart] = 0; int32_t caretX = x + gfx_get_string_width(lineBuffer); int32_t caretY = y + 14; gfx_fill_rect(dpi, caretX, caretY, caretX + 6, caretY + 1, PALETTE_INDEX_56); } } }
void mapgen_generate(mapgen_settings *settings) { sint32 x, y, mapSize, floorTexture, wallTexture, waterLevel; rct_map_element *mapElement; util_srand((sint32)platform_get_ticks()); mapSize = settings->mapSize; floorTexture = settings->floor; wallTexture = settings->wall; waterLevel = settings->water_level; if (floorTexture == -1) floorTexture = BaseTerrain[util_rand() % countof(BaseTerrain)]; if (wallTexture == -1) { // Base edge type on surface type switch (floorTexture) { case TERRAIN_DIRT: wallTexture = TERRAIN_EDGE_WOOD_RED; break; case TERRAIN_ICE: wallTexture = TERRAIN_EDGE_ICE; break; default: wallTexture = TERRAIN_EDGE_ROCK; break; } } map_clear_all_elements(); // Initialise the base map map_init(mapSize); for (y = 1; y < mapSize - 1; y++) { for (x = 1; x < mapSize - 1; x++) { mapElement = map_get_surface_element_at(x, y); map_element_set_terrain(mapElement, floorTexture); map_element_set_terrain_edge(mapElement, wallTexture); mapElement->base_height = settings->height; mapElement->clearance_height = settings->height; } } // Create the temporary height map and initialise _heightSize = mapSize * 2; _height = (uint8*)malloc(_heightSize * _heightSize * sizeof(uint8)); memset(_height, 0, _heightSize * _heightSize * sizeof(uint8)); if (1) { mapgen_simplex(settings); mapgen_smooth_height(2 + (util_rand() % 6)); } else { // Keep overwriting the map with rough circular blobs of different sizes and heights. // This procedural method can produce intersecting contour like land and lakes. // Large blobs, general shape of map mapgen_blobs(6, _heightSize / 2, _heightSize * 4, 4, 16); // Medium blobs mapgen_blobs(12, _heightSize / 16, _heightSize / 8, 4, 18); // Small blobs, small hills and lakes mapgen_blobs(32, _heightSize / 32, _heightSize / 16, 4, 18); // Smooth the land so that there aren't cliffs round every blob. mapgen_smooth_height(2); } // Set the game map to the height map mapgen_set_height(); free(_height); // Set the tile slopes so that there are no cliffs while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) { } // Add the water mapgen_set_water_level(waterLevel); // Add sandy beaches sint32 beachTexture = floorTexture; if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) { switch (util_rand() % 4) { case 0: beachTexture = TERRAIN_SAND; break; case 1: beachTexture = TERRAIN_SAND_LIGHT; break; } } for (y = 1; y < mapSize - 1; y++) { for (x = 1; x < mapSize - 1; x++) { mapElement = map_get_surface_element_at(x, y); if (mapElement->base_height < waterLevel + 6) map_element_set_terrain(mapElement, beachTexture); } } // Place the trees if (settings->trees != 0) mapgen_place_trees(); map_reorganise_elements(); }