예제 #1
0
파일: compiler.c 프로젝트: lerno/coil
static void and()
{
	// Skip the right argument if the left is true.
	emit_byte(OP_AND);
	int jump = current_chunk()->size;
	emit_byte(0xFF);
	parse_precedence(PREC_AND);
	current_chunk()->code[jump] = (uint8_t)(current_chunk()->size - jump - 1);
}
예제 #2
0
파일: font.cpp 프로젝트: oys0317/opensanguo
//Splits the UTF-8 text into text_chunks using the same font.
static std::vector<text_chunk> split_text(std::string const & utf8_text) {
	text_chunk current_chunk(0);
	std::vector<text_chunk> chunks;

	if (utf8_text.empty())
		return chunks;

	try {
		utils::utf8_iterator ch(utf8_text);
		if(size_t(*ch) < font_map.size() && font_map[size_t(*ch)] >= 0) {
			current_chunk.subset = font_map[size_t(*ch)];
		}
		for(utils::utf8_iterator end = utils::utf8_iterator::end(utf8_text); ch != end; ++ch) {
			if(size_t(*ch) < font_map.size() &&
					font_map[size_t(*ch)] >= 0 &&
					font_map[size_t(*ch)] != current_chunk.subset) {
				//null-terminate ucs2_text so we can pass it to SDL_ttf later
				current_chunk.ucs2_text.push_back(0);
				chunks.push_back(current_chunk);
				current_chunk.text = "";
				current_chunk.ucs2_text.clear();
				current_chunk.subset = font_map[size_t(*ch)];
			}
			current_chunk.ucs2_text.push_back(static_cast<Uint16>(*ch));
			current_chunk.text.append(ch.substr().first, ch.substr().second);
		}
		if (!current_chunk.text.empty()) {
			chunks.push_back(current_chunk);
		}
	}
	catch(utils::invalid_utf8_exception e) {
		WRN_FT << "Invalid UTF-8 string: \"" << utf8_text << "\"\n";
	}
	return chunks;
}
예제 #3
0
파일: font.cpp 프로젝트: dailin/wesnoth
//Splits the UTF-8 text into text_chunks using the same font.
static std::vector<text_chunk> split_text(std::string const & utf8_text) {
	text_chunk current_chunk(0);
	std::vector<text_chunk> chunks;

	if (utf8_text.empty())
		return chunks;

	try {
		utf8::iterator ch(utf8_text);
		int sub = char_blocks.get_id(*ch);
		if (sub >= 0) current_chunk.subset = sub;
		for(utf8::iterator end = utf8::iterator::end(utf8_text); ch != end; ++ch)
		{
			sub = char_blocks.get_id(*ch);
			if (sub >= 0 && sub != current_chunk.subset) {
				chunks.push_back(current_chunk);
				current_chunk.text.clear();
				current_chunk.subset = sub;
			}
			current_chunk.text.append(ch.substr().first, ch.substr().second);
		}
		if (!current_chunk.text.empty()) {
			chunks.push_back(current_chunk);
		}
	}
	catch(utf8::invalid_utf8_exception&) {
		WRN_FT << "Invalid UTF-8 string: \"" << utf8_text << "\"" << std::endl;
	}
	return chunks;
}
예제 #4
0
파일: compiler.c 프로젝트: lerno/coil
static void end_compiler()
{
	emit_byte(OP_RETURN);
#ifdef DEBUG_PRINT_CODE
	if (!parser.had_error)
	{
		disassemble_chunk(current_chunk(), "code");
	}
#endif
}
예제 #5
0
파일: compiler.c 프로젝트: lerno/coil
static uint8_t make_constant(Value value)
{
	int constant = chunk_add_constant(current_chunk(), value);
	if (constant > UINT8_MAX)
	{
		error("Too many constants in one chunk.");
		return 0;
	}

	return (uint8_t)constant;
}
예제 #6
0
파일: compiler.c 프로젝트: lerno/coil
static void emit_byte(uint8_t byte)
{
	chunk_write(current_chunk(), byte, parser.previous.line);
}
예제 #7
0
void TileRenderer::renderTile(const TilePos& tile_pos, const TilePos& tile_offset,
		RGBAImage& tile) {
	// some vars, set correct image size
	int block_size = state.images->getBlockImageSize();
	int tile_size = state.images->getTileSize();
	tile.setSize(tile_size, tile_size);

	// get the maximum count of water blocks
	// blitted about each over, until they are nearly opaque
	int max_water = state.images->getMaxWaterNeededOpaque();

	// all visible blocks which are rendered in this tile
	std::set<RenderBlock> blocks;

	// call start method of the rendermodes
	for (size_t i = 0; i < rendermodes.size(); i++)
		rendermodes[i]->start();

	// iterate over the highest blocks in the tile
	// we use as tile position tile_pos+tile_offset because the offset means that
	// we treat the tile position as tile_pos, but it's actually tile_pos+tile_offset
	for (TileTopBlockIterator it(tile_pos + tile_offset, block_size, tile_size);
			!it.end(); it.next()) {
		// water render behavior n1:
		// are we already in a row of water?
		bool in_water = false;

		// water render behavior n2:
		// water counter, how many water blocks are at the moment in this row?
		int water = 0;

		// the render block objects in our current block row
		std::set<RenderBlock> row_nodes;
		// then iterate over the blocks, which are on the tile at the same position,
		// beginning from the highest block
		for (BlockRowIterator block(it.current); !block.end(); block.next()) {
			// get current chunk position
			mc::ChunkPos current_chunk(block.current);

			// check if current chunk is not null
			// and if the chunk wasn't replaced in the cache (i.e. position changed)
			if (state.chunk == nullptr || state.chunk->getPos() != current_chunk)
				// get chunk if not
				//if (!state.world->hasChunkSection(current_chunk, block.current.y))
				//	continue;
				state.chunk = state.world->getChunk(current_chunk);
			if (state.chunk == nullptr) {
				// here is nothing (= air),
				// so reset state if we are in water
				in_water = false;
				continue;
			}

			// get local block position
			mc::LocalBlockPos local(block.current);

			// now get block id
			uint16_t id = state.chunk->getBlockID(local);
			// air is completely transparent so continue
			if (id == 0) {
				in_water = false;
				continue;
			}

			// now get the block data
			uint16_t data = state.chunk->getBlockData(local);

			// check if a rendermode hides this block
			bool visible = true;
			for (size_t i = 0; i < rendermodes.size(); i++) {
				if (rendermodes[i]->isHidden(block.current, id, data)) {
					visible = false;
					break;
				}
			}
			if (!visible)
				continue;

			bool is_water = (id == 8 || id == 9) && data == 0;
			if (is_water && !water_preblit) {
				// water render behavior n1:
				// render only the top sides of the water blocks
				// and darken the ground with the lighting data
				// used for lighting rendermode

				// if we are already in water, skip checking this water block
				if (is_water && in_water)
					continue;
				in_water = is_water;

			} else if (water_preblit) {
				// water render behavior n2:
				// render the top side of every water block
				// have also preblit water blocks to skip redundant alphablitting

				// no lighting is needed because the 'opaque-water-effect'
				// is created by blitting the top sides of the water blocks
				// one above the other

				if (!is_water) {
					// if not water, reset the counter
					water = 0;
				} else {
					water++;

					// when we have enough water in a row
					// we can stop searching more blocks
					// and replace the already added render blocks with a preblit water block
					if (water > max_water) {
						std::set<RenderBlock>::const_iterator it = row_nodes.begin();
						// iterate through the render blocks in this row
						while (it != row_nodes.end()) {
							std::set<RenderBlock>::const_iterator current = it++;
							// check if we have reached the top most water block
							if (it == row_nodes.end() || (it->id != 8 && it->id != 9)) {
								RenderBlock top = *current;
								row_nodes.erase(current);

								// check for neighbors
								mc::Block south, west;
								south = state.getBlock(top.pos + mc::DIR_SOUTH);
								west = state.getBlock(top.pos + mc::DIR_WEST);

								bool neighbor_south = (south.id == 8 || south.id == 9);
								if (neighbor_south)
									data |= DATA_SOUTH;
								bool neighbor_west = (west.id == 8 || west.id == 9);
								if (neighbor_west)
									data |= DATA_WEST;

								// get image and replace the old render block with this
								top.image = state.images->getOpaqueWater(neighbor_south,
										neighbor_west);

								// don't forget the rendermodes
								for (size_t i = 0; i < rendermodes.size(); i++)
									rendermodes[i]->draw(top.image, top.pos, id, data);

								row_nodes.insert(top);
								break;

							} else {
								// water render block
								row_nodes.erase(current);
							}
						}

						break;
					}
				}
			}

			// check for special data (neighbor related)
			// get block image, check for transparency, create render block...
			data = checkNeighbors(block.current, id, data);
			//if (is_water && (data & DATA_WEST) && (data & DATA_SOUTH))
			//	continue;
			RGBAImage image;
			bool transparent = state.images->isBlockTransparent(id, data);

			// check for biome data
			if (Biome::isBiomeBlock(id, data))
				image = state.images->getBiomeDependBlock(id, data, getBiomeOfBlock(block.current, state.chunk));
			else
				image = state.images->getBlock(id, data);

			RenderBlock node;
			node.x = it.draw_x;
			node.y = it.draw_y;
			node.pos = block.current;
			node.image = image;
			node.id = id;
			node.data = data;

			// let the rendermodes do their magic with the block image
			for (size_t i = 0; i < rendermodes.size(); i++)
				rendermodes[i]->draw(node.image, node.pos, id, data);

			// insert into current row
			row_nodes.insert(node);

			// if this block is not transparent, then break
			if (!transparent)
				break;
		}

		// iterate through the created render blocks
		for (std::set<RenderBlock>::const_iterator it = row_nodes.begin();
		        it != row_nodes.end(); ++it) {
			std::set<RenderBlock>::const_iterator next = it;
			next++;
			// insert render block to
			if (next == row_nodes.end()) {
				blocks.insert(*it);
			} else {
				// skip unnecessary leaves
				if (it->id == 18 && next->id == 18 && (next->data & 3) == (it->data & 3))
					continue;
				blocks.insert(*it);
			}
		}
	}

	// now blit all blocks
	for (std::set<RenderBlock>::const_iterator it = blocks.begin(); it != blocks.end();
			++it) {
		tile.alphablit(it->image, it->x, it->y);
	}

	// call the end method of the rendermodes
	for (size_t i = 0; i < rendermodes.size(); i++)
		rendermodes[i]->end();
}