static void find_nearest_block(struct group *group, struct ray const *ray, struct nearest *nearest) { struct groupdata *groupdata = group->data; struct ray groupspaceray; vec3_subtract(&groupspaceray.origin, &ray->origin, &group->position); groupspaceray.direction = ray->direction; buffer *buffer = create_buffer(); ptrarray *blocks = groupdata->blocks; size_t blockcount = ptrarray_count(blocks); for (size_t i = 0; i < blockcount; ++i) { block *block = get_ptrarray(blocks, i); get_block_triangles(block, buffer); triangle *tris = buffer_data(buffer); size_t tricount = buffer_count(buffer, sizeof(struct triangle)); for (size_t j = 0; j < tricount; ++j) { float temp; if (ray_intersect_triangle(&temp, &groupspaceray, &tris[j])) { /* * Use <= for distance comparsion here so that when there are * multiple candidates for selection the last block added will * be selected. It is useful after pasting that the new blocks * can be dragged to a new location. */ if (temp <= nearest->distance) { nearest->distance = temp; nearest->group = group; nearest->block = block; nearest->triangle = tris[j]; } } } clear_buffer(buffer); } destroy_buffer(buffer); struct ptrarray *groups = groupdata->groups; size_t groupcount = ptrarray_count(groups); for (size_t i = 0; i < groupcount; ++i) { struct group *childgroup = get_ptrarray(groups, i); find_nearest_block(childgroup, ray, nearest); } }
void uart1_write(uint8_t byte) { if ((UCSR1A & (1 << UDRE1)) && buffer_count(&buffer_tx1) == 0) { UDR1 = byte; // write buffer empty and no uart write in progress -> write out directly return; } while (buffer_is_full(&buffer_tx1)); // write buffer full - wait! uart1_int_disable(); buffer_write(&buffer_tx1, byte); uart1_int_enable(); }
void uart0_write(uint8_t byte) { if (buffer_count(&buffer_tx0) == 0 && (UCSR0A & (1 << UDRE0))) { UDR0 = byte; // write buffer empty and no uart write in progress -> write out directly return; } while (buffer_is_full(&buffer_tx0)); // write buffer full - wait! uart0_int_disable(); buffer_write(&buffer_tx0, byte); uart0_int_enable(); }
internal void PopulateAbundantNumberList() { u32 *List = 0; for(u32 PotentialAbundantNumber = 1; PotentialAbundantNumber < AbundantNumberLimit; ++PotentialAbundantNumber) { if(IsAbundant(PotentialAbundantNumber)) { buffer_push(List, PotentialAbundantNumber); } } AbundantNumberList.List = List; AbundantNumberList.Length = buffer_count(List); }
static void draw_group_(struct group const *group) { struct groupdata *groupdata = group->data; vertex *vertices = buffer_data(groupdata->vertices); size_t vertexcount = buffer_count(groupdata->vertices, sizeof(struct vertex)); glPushMatrix(); glTranslatef(group->position.x, group->position.y, group->position.z); glNormalPointer(GL_FLOAT, sizeof(struct vertex), &vertices->normal); glVertexPointer(3, GL_FLOAT, sizeof(struct vertex), &vertices->position); glDrawArrays(GL_TRIANGLES, 0, vertexcount); size_t groupcount = ptrarray_count(groupdata->groups); for (size_t i = 0; i < groupcount; ++i) { draw_group_(get_ptrarray(groupdata->groups, i)); } glPopMatrix(); }
static void append_triangles(struct groupdata *groupdata, buffer *buffer) { triangle *triangles = buffer_data(buffer); size_t trianglecount = buffer_count(buffer, sizeof(struct triangle)); for (size_t i = 0; i < trianglecount; ++i) { vec3 normal; triangle_normal(&normal, &triangles[i]); vec3_normalize(&normal, &normal); vertex vertices[3] = { {normal, triangles[i].a}, {normal, triangles[i].b}, {normal, triangles[i].c} }; append_buffer(groupdata->vertices, vertices, sizeof(vertices)); } }
void uart0_write_buffer(const uint8_t *data, uint8_t size) { uint8_t i = 0; if (buffer_count(&buffer_tx0) == 0 && (UCSR0A & (1 << UDRE0))) { if (size > 1) { UCSR0B &= (uint8_t)~((1 << TXCIE0)); // disable tx interrupt to have at least 1 byte in tx buffer before interrupt handler is called } UDR0 = data[i++]; // write buffer empty and no uart write in progress -> write out first byte directly } while (i < size) { while (buffer_is_full(&buffer_tx0)) { UCSR0B |= (1 << TXCIE0); // write buffer full, enable tx irq to send out data and wait... } UCSR0B &= (uint8_t)~((1 << TXCIE0)); // disable transmit interrupt to protect tx buffer buffer_write(&buffer_tx0, data[i]); ++i; } UCSR0B |= (1 << TXCIE0); // enable transmit interrupt }
uint8_t uart1_bytes_available() { return buffer_count(&buffer_rx1); }
int main(int argc, char* argv[]) { uint8_t input[FRAME_WIDTH * FRAME_HEIGHT]; if (renderer_create(FRAME_WIDTH, FRAME_HEIGHT, RENDER_VISIBLE) < 0) return -1; stream_t* stream = stream_create(); frames_t* frames = &(stream->frames); tiles_t* tiles = &(stream->tiles); size_t actual = 0; for (int index = FIRST_INDEX; index <= LAST_INDEX; ++index) { char path[256]; sprintf(path, "images/image-%04d.raw", index); FILE* fp = fopen(path, "rb"); if (!fp) break; if (fread(input, FRAME_WIDTH*FRAME_HEIGHT, 1, fp) < 1) break; fclose(fp); frame_t frame; tile_index_t* indices = frame.tiles; for (int y = 0; y < FRAME_HEIGHT; y += TILE_HEIGHT) { for (int x = 0; x < FRAME_WIDTH; x += TILE_WIDTH) { tile_t tile; *(indices++) = tiles_insert(tiles, input + x + y * FRAME_WIDTH, 200, FRAME_WIDTH); ++ actual; } } frames_add(frames, &frame); if (index % 10 == 0) { if (renderer_update(FRAME_WIDTH, FRAME_HEIGHT, input, 0) < 0) return 0; } fprintf(stderr, "\rpath: %s, frames: %lu tiles: %lu/%lu blocks: %lu", path, buffer_count(&(frames->buffer)), buffer_count(&(tiles->buffer)), actual, buffer_count(&(tiles->blocks.buffer))); } renderer_destroy(); fprintf(stderr, "\n"); stream_optimize_blocks(stream, BLOCK_PASSES, MAX_BLOCK_ERROR); stream_optimize_tiles(stream, MAX_TILE_ERROR); // stream_optimize_frames(stream); fprintf(stderr, "\nsaving...\n"); FILE* out = fopen("anim.bin", "wb"); if (stream_save(stream, out) < 0) { fprintf(stderr, "failed to save stream\n"); return -1; } fclose(out); stream_destroy(stream); return 0; }