void *malloc(unsigned int size) { // try small allocation first for (int i = 0; i < NUM_BLOCKSIZES; i++) { if (size <= smallblock[i].blocksize) { struct smallblock_info *elt, *head = &smallblock[i]; int pieces_per_page = PAGE_SIZE / head->blocksize; // for each existing page of this blocksize for (elt = head->next; elt != head; elt = elt->next) { // for each of the blocks on this page (note: block 0 is reserved) for (int j = 1; j < pieces_per_page; j++) { // if the block is free if (bitmap_get(elt->bitmap, j) == 0) { // then use that block bitmap_set(elt->bitmap, j, 1); void *pointer = (void *)elt + j * elt->blocksize; return pointer; } } } // there were no existing pages with free blocks void *p = alloc_pages(1); // first part of page is for accounting elt = p; elt->magic = 0xfeedface; elt->blocksize = head->blocksize; memset(elt->bitmap, 0, 16); // add to existing list elt->next = head; elt->prev = head->prev; elt->next->prev = elt; elt->prev->next = elt; // remainder of block is the actual data bitmap_set(elt->bitmap, 1, 1); void *pointer = p + 1 * elt->blocksize; return pointer; } } // resort to large allocation if it wasn't small size += sizeof(struct bigblock_info); // accounting overhead int n = (size + PAGE_SIZE - 1) / PAGE_SIZE; void *p = alloc_pages(n); // first part of page is for accounting struct bigblock_info *elt = p; elt->magic = 0xf00dface; elt->pagecount = n; // remainder of page is the actual data void *pointer = (p + sizeof(struct bigblock_info)); return pointer; }
void wavefront_task_consider( struct bitmap *b, struct list *list, int x, int y ) { int i,j; for(i=0;(i<block_size) && (x+i-xstart+1)<=xsize;i++) { if(bitmap_get(b,x+i-xstart+1,y-ystart)!=WAVEFRONT_TASK_STATE_COMPLETE) break; } for(j=0;(j<block_size) && (y+j-ystart+1)<=ysize;j++) { if(bitmap_get(b,x-xstart,y+j-ystart+1)!=WAVEFRONT_TASK_STATE_COMPLETE) break; } if(i==0 || j==0) return; struct wavefront_task *t = wavefront_task_create(x,y,i,j); wavefront_task_mark_range(t,b,WAVEFRONT_TASK_STATE_READY); list_push_head(list,t); }
TEST_END TEST_BEGIN(test_bitmap_sfu) { size_t i; for (i = 1; i <= BITMAP_MAXBITS; i++) { bitmap_info_t binfo; bitmap_info_init(&binfo, i); { size_t j; bitmap_t *bitmap = (bitmap_t *)malloc( bitmap_size(&binfo)); bitmap_init(bitmap, &binfo); /* Iteratively set bits starting at the beginning. */ for (j = 0; j < i; j++) { assert_zd_eq(bitmap_sfu(bitmap, &binfo), j, "First unset bit should be just after " "previous first unset bit"); } assert_true(bitmap_full(bitmap, &binfo), "All bits should be set"); /* * Iteratively unset bits starting at the end, and * verify that bitmap_sfu() reaches the unset bits. */ for (j = i - 1; j < i; j--) { /* (i..0] */ bitmap_unset(bitmap, &binfo, j); assert_zd_eq(bitmap_sfu(bitmap, &binfo), j, "First unset bit should the bit previously " "unset"); bitmap_unset(bitmap, &binfo, j); } assert_false(bitmap_get(bitmap, &binfo, 0), "Bit should be unset"); /* * Iteratively set bits starting at the beginning, and * verify that bitmap_sfu() looks past them. */ for (j = 1; j < i; j++) { bitmap_set(bitmap, &binfo, j - 1); assert_zd_eq(bitmap_sfu(bitmap, &binfo), j, "First unset bit should be just after the " "bit previously set"); bitmap_unset(bitmap, &binfo, j); } assert_zd_eq(bitmap_sfu(bitmap, &binfo), i - 1, "First unset bit should be the last bit"); assert_true(bitmap_full(bitmap, &binfo), "All bits should be set"); free(bitmap); } } }
static int info_scroll( int n, REGION * clip, int * z, int * drawme ) { * z = scrolls[n].z; * drawme = 1; * clip = * scrolls[n].region; scroll_update( n ); // Force clean map (need optimization) if ( scrolls[n].destid ) gr_clear_region( bitmap_get( scrolls[n].destfile, scrolls[n].destid ), scrolls[n].region ); return 1; }
GRAPH * instance_graph( INSTANCE * i ) { int * xgraph, c, a ; if (( xgraph = ( int * ) LOCDWORD( librender, i, XGRAPH ) ) ) // Get offset of XGRAPH table { c = *xgraph++; // Get number of graphs ids in XGRAPH table if ( c ) { // Normalize ANGLE a = LOCINT32( librender, i, ANGLE ) % 360000 ; if ( a < 0 ) a += 360000 ; // Get graph id in XGRAPH table to draw c = xgraph[a * c / 360000] ; // If graph id value is negative, then graphic must be mirrored if ( c < 0 ) { c = -c; LOCDWORD( librender, i, XGRAPH_FLAGS ) = B_HMIRROR; } else { LOCDWORD( librender, i, XGRAPH_FLAGS ) = 0; } // Get GRAPH * to draw return bitmap_get( LOCDWORD( librender, i, FILEID ), c ) ; } } // Get GRAPH * to draw if (( c = LOCDWORD( librender, i, GRAPHID ) ) ) { return bitmap_get( LOCDWORD( librender, i, FILEID ), c ) ; } return 0 ; // No graph to draw }
/** Merge two zones. * * Assume z1 & z2 are locked and compatible and zones lock is * locked. * * @param z1 First zone to merge. * @param z2 Second zone to merge. * @param old_z1 Original data of the first zone. * @param confdata Merged zone configuration data. * */ NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, void *confdata) { ASSERT(zones.info[z1].flags & ZONE_AVAILABLE); ASSERT(zones.info[z2].flags & ZONE_AVAILABLE); ASSERT(zones.info[z1].flags == zones.info[z2].flags); ASSERT(zones.info[z1].base < zones.info[z2].base); ASSERT(!overlaps(zones.info[z1].base, zones.info[z1].count, zones.info[z2].base, zones.info[z2].count)); /* Difference between zone bases */ pfn_t base_diff = zones.info[z2].base - zones.info[z1].base; zones.info[z1].count = base_diff + zones.info[z2].count; zones.info[z1].free_count += zones.info[z2].free_count; zones.info[z1].busy_count += zones.info[z2].busy_count; bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count, confdata + (sizeof(frame_t) * zones.info[z1].count)); bitmap_clear_range(&zones.info[z1].bitmap, 0, zones.info[z1].count); zones.info[z1].frames = (frame_t *) confdata; /* * Copy frames and bits from both zones to preserve parents, etc. */ for (size_t i = 0; i < old_z1->count; i++) { bitmap_set(&zones.info[z1].bitmap, i, bitmap_get(&old_z1->bitmap, i)); zones.info[z1].frames[i] = old_z1->frames[i]; } for (size_t i = 0; i < zones.info[z2].count; i++) { bitmap_set(&zones.info[z1].bitmap, base_diff + i, bitmap_get(&zones.info[z2].bitmap, i)); zones.info[z1].frames[base_diff + i] = zones.info[z2].frames[i]; } }
void update_slots_used_single(void *msg_hdr, uint32_t *bitmap, struct netmap_ring *ring) { struct msg_transaction_update_single *msg = msg_hdr; bitmap_clear(bitmap, msg->ring_idx); // reduce the range of slots in use as indicated by the bitmap while (!bitmap_get(bitmap, (ring->num_slots + ring->cur - ring->reserved) % ring->num_slots)) { ring->reserved--; if (!ring->reserved) break; } }
int bitmap_save( struct bitmap *m, const char *path ) { FILE *file; struct bmp_header header; int i, j; unsigned char *scanline, *s; file = fopen(path,"wb"); if(!file) return 0; memset(&header,0,sizeof(header)); header.magic1 = 'B'; header.magic2 = 'M'; header.size = m->width*m->height*3; header.offset = sizeof(header); header.infosize = sizeof(header)-14; header.width = m->width; header.height = m->height; header.planes = 1; header.bits = 24; header.compression = 0; header.imagesize = m->width*m->height*3; header.xres = 1000; header.yres = 1000; fwrite(&header,1,sizeof(header),file); /* if the scanline is not a multiple of four, round it up. */ int padlength = 4 - (m->width*3)%4; if(padlength==4) padlength=0; scanline = malloc(header.width*3); for(j=0;j<m->height;j++) { s = scanline; for(i=0;i<m->width;i++) { int rgba = bitmap_get(m,i,j); *s++ = GET_BLUE(rgba); *s++ = GET_GREEN(rgba); *s++ = GET_RED(rgba); } fwrite(scanline,1,m->width*3,file); fwrite(scanline,1,padlength,file); } free(scanline); fclose(file); return 1; }
char * bitmap_string(bitmap_t *bitmap, char *buf, size_t len) { int i; char *p = buf, *q = buf + len; for (i = 0; i < bitmap->num_bits; i++) { if (p >= q) break; *p++ = bitmap_get(bitmap, i) ? '1' : '0'; } if (p < q) *p = '\0'; return buf; }
int main() { int i = 0, k = 1; pthread_t pid; bitmap_t bmp = bitmap_alloc(SIZE); check(bmp, k++); check(bmp, k++); check(bmp, k++); check(bmp, k++); check(bmp, k++); printf("index : %lu = %d\n", SIZE + 1, bitmap_get(bmp, SIZE + 1)); printf("index : %lu = %d\n", SIZE + 66, bitmap_get(bmp, SIZE + 66)); for (i = 0; i < SIZE; i++) { unsigned long index = bitmap_zero_index(bmp); printf("bitmap_zero_index : %d\n", index); bitmap_set(bmp, index); } return 0; }
JEMALLOC_INLINE_C void arena_slab_reg_dalloc(tsdn_t *tsdn, extent_t *slab, arena_slab_data_t *slab_data, void *ptr) { szind_t binind = slab_data->binind; const arena_bin_info_t *bin_info = &arena_bin_info[binind]; size_t regind = arena_slab_regind(slab, binind, ptr); assert(slab_data->nfree < bin_info->nregs); /* Freeing an unallocated pointer can cause assertion failure. */ assert(bitmap_get(slab_data->bitmap, &bin_info->bitmap_info, regind)); bitmap_unset(slab_data->bitmap, &bin_info->bitmap_info, regind); slab_data->nfree++; }
TEST_END static void test_bitmap_init_body(const bitmap_info_t *binfo, size_t nbits) { size_t i; bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo)); assert_ptr_not_null(bitmap, "Unexpected malloc() failure"); bitmap_init(bitmap, binfo); for (i = 0; i < nbits; i++) { assert_false(bitmap_get(bitmap, binfo, i), "Bit should be unset"); } free(bitmap); }
void update_arp_cache(struct arp_cache *arp_cache, struct thread_context *contexts, cqueue_spsc *q) { uint32_t i, j; struct arp_cache_entry *e; struct timeval t; struct in_addr ip; int rv; rv = gettimeofday(&t, NULL); assert(rv == 0); for (i=0; i < arp_cache->num_entries; i++) { e = &arp_cache->values[i]; // skip uninitialized entries if (e->timestamp.tv_sec == 0) continue; // failed to get a response, so notify waiters if (e->retries == ARP_CACHE_RETRY_LIMIT) { ip.s_addr = arp_cache->baseline + htonl(i); for (j=0; j < MAX_THREADS; j++) { if (bitmap_get(e->waiters, j)) send_msg_get_mac_reply(&contexts[j], &ip, ÐER_ADDR_ZERO); } memset(e, 0, sizeof(*e)); continue; } // time's up, resend the request if (timeval_gte(&t, &e->timestamp)) { ip.s_addr = arp_cache->baseline + htonl(i); rv = send_pkt_arp_request(q, &ip); if (!rv) continue; e->retries++; e->timestamp.tv_sec = t.tv_sec; e->timestamp.tv_usec = t.tv_usec + ARP_CACHE_RETRY_INTERVAL; if (e->timestamp.tv_usec > 999999) { e->timestamp.tv_sec++; e->timestamp.tv_usec-=1000000; } } } // for (arp cache entries) }
TTF_Bitmap *copy_bitmap(TTF_Bitmap *bitmap) { if (!bitmap) { return NULL; } TTF_Bitmap *copy = create_bitmap(bitmap->w, bitmap->h, bitmap->c); int y; for (y = 0; y < bitmap->h; y++) { int x; for (x = 0; x < bitmap->w; x++) { bitmap_set(copy, x, y, bitmap_get(bitmap, x, y)); } } return copy; }
TEST_END static void test_bitmap_sfu_body(const bitmap_info_t *binfo, size_t nbits) { size_t i; bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo)); assert_ptr_not_null(bitmap, "Unexpected malloc() failure"); bitmap_init(bitmap, binfo); /* Iteratively set bits starting at the beginning. */ for (i = 0; i < nbits; i++) { assert_zd_eq(bitmap_sfu(bitmap, binfo), i, "First unset bit should be just after previous first unset " "bit"); } assert_true(bitmap_full(bitmap, binfo), "All bits should be set"); /* * Iteratively unset bits starting at the end, and verify that * bitmap_sfu() reaches the unset bits. */ for (i = nbits - 1; i < nbits; i--) { /* (nbits..0] */ bitmap_unset(bitmap, binfo, i); assert_zd_eq(bitmap_sfu(bitmap, binfo), i, "First unset bit should the bit previously unset"); bitmap_unset(bitmap, binfo, i); } assert_false(bitmap_get(bitmap, binfo, 0), "Bit should be unset"); /* * Iteratively set bits starting at the beginning, and verify that * bitmap_sfu() looks past them. */ for (i = 1; i < nbits; i++) { bitmap_set(bitmap, binfo, i - 1); assert_zd_eq(bitmap_sfu(bitmap, binfo), i, "First unset bit should be just after the bit previously " "set"); bitmap_unset(bitmap, binfo, i); } assert_zd_eq(bitmap_sfu(bitmap, binfo), nbits - 1, "First unset bit should be the last bit"); assert_true(bitmap_full(bitmap, binfo), "All bits should be set"); free(bitmap); }
static void test_bitmap_sfu(void) { size_t i; for (i = 1; i <= MAXBITS; i++) { bitmap_info_t binfo; bitmap_info_init(&binfo, i); { ssize_t j; bitmap_t *bitmap = malloc(sizeof(bitmap_t) * bitmap_info_ngroups(&binfo)); bitmap_init(bitmap, &binfo); /* Iteratively set bits starting at the beginning. */ for (j = 0; j < i; j++) assert(bitmap_sfu(bitmap, &binfo) == j); assert(bitmap_full(bitmap, &binfo)); /* * Iteratively unset bits starting at the end, and * verify that bitmap_sfu() reaches the unset bits. */ for (j = i - 1; j >= 0; j--) { bitmap_unset(bitmap, &binfo, j); assert(bitmap_sfu(bitmap, &binfo) == j); bitmap_unset(bitmap, &binfo, j); } assert(bitmap_get(bitmap, &binfo, 0) == false); /* * Iteratively set bits starting at the beginning, and * verify that bitmap_sfu() looks past them. */ for (j = 1; j < i; j++) { bitmap_set(bitmap, &binfo, j - 1); assert(bitmap_sfu(bitmap, &binfo) == j); bitmap_unset(bitmap, &binfo, j); } assert(bitmap_sfu(bitmap, &binfo) == i - 1); assert(bitmap_full(bitmap, &binfo)); free(bitmap); } } }
int draw_bitmap(TTF_Bitmap *canvas, TTF_Bitmap *bitmap, int x, int y) { CHECKPTR(canvas); CHECKPTR(bitmap); if (!IN(x, 0, canvas->w-1) || !IN(y, 0, canvas->h-1)) { warn("failed to draw bitmap out of bounds"); return FAILURE; } /* Out of bounds checking is also done in bitmap_set,_get() */ for (int yb = 0; yb < bitmap->h; yb++) { for (int xb = 0; xb < bitmap->w; xb++) { bitmap_set(canvas, x+xb, y+yb, bitmap_get(bitmap, xb, yb)); } } return SUCCESS; }
int main() { uint32_t i, j, k; output(2); for (i = 0; i < BITMAP_SIZE; i++) { if (bitmap_get(i)) continue; output(3+2*i); for (j = 2*(3+2*i);; j += 3+2*i) { if (j%2 == 0) continue; k = (j-3)/2; if (k >= BITMAP_SIZE) break; bitmap_set(k); } } return 0; }
static void test_bitmap_init(void) { size_t i; for (i = 1; i <= MAXBITS; i++) { bitmap_info_t binfo; bitmap_info_init(&binfo, i); { size_t j; bitmap_t bitmap[bitmap_info_ngroups(&binfo)]; bitmap_init(bitmap, &binfo); for (j = 0; j < i; j++) assert(bitmap_get(bitmap, &binfo, j) == false); } } }
static int add_to_include_set(struct bitmap *base, struct commit *commit) { khiter_t hash_pos; uint32_t bitmap_pos = find_object_pos(commit->object.sha1); if (bitmap_get(base, bitmap_pos)) return 0; hash_pos = kh_get_sha1(writer.bitmaps, commit->object.sha1); if (hash_pos < kh_end(writer.bitmaps)) { struct bitmapped_commit *bc = kh_value(writer.bitmaps, hash_pos); bitmap_or_ewah(base, bc->bitmap); return 0; } bitmap_set(base, bitmap_pos); return 1; }
void free(void *pointer) { // round down to nearest page boundary void *page = (void *)((unsigned int)pointer & ~(PAGE_SIZE-1)); // some trivial sanity checks if (page < (void *)0xC0000000) { printf("free: virtual address %p is too low to have come from malloc\n", pointer); shutdown(); } // first word on page should be a magic number, second should be blocksize if (pointer - page < 8) { printf("free: virtual address %p is not aligned properly to have come from malloc\n", pointer); shutdown(); } unsigned int *magic = page; if (*magic == 0xfeedface) { // small block struct smallblock_info *elt = page; // calculate index into blocks of page int idx = (pointer - page) / elt->blocksize; if (idx < 1 || pointer != (page + idx * elt->blocksize)) { printf("free: virtual address %p is not aligned properly to have come from malloc\n", pointer); shutdown(); } if (bitmap_get(elt->bitmap, idx) == 0) { printf("free: virtual address %p was already freed, or has not been allocated\n", pointer); shutdown(); } bitmap_set(elt->bitmap, idx, 0); // we could, if we want, free the whole page if all the blocks on the page // are empty, but we won't bother } else if (*magic == 0xf00dface) { // big block struct bigblock_info *elt = page; elt->magic = 0xdeadf00d; // erase the magic number free_pages(page, elt->pagecount); } else { printf("free: virtual address %p has bad magic (0x%x), either didn't come from malloc, was freed, or is corrupted\n", pointer, *magic); shutdown(); } }
/* Add an inode back to free list */ void ifree(inodenum_t inum) { blocknum_t bit = -1; blocknum_t block_offset; fs_lock(mainsb); /* Set the inode to free */ bit = inum; block_offset = bit / BITS_PER_BLOCK; if (bitmap_get(mainsb->inode_bitmap, bit) == 1) { mainsb->free_inodes++; } bitmap_clear(mainsb->inode_bitmap, bit); bpush(block_offset + mainsb->inode_bitmap_first, (char*) mainsb->inode_bitmap + block_offset * DISK_BLOCK_SIZE); fs_unlock(mainsb); }
/* Iterate over a valid jemalloc small allocation run, calling callback for each * active allocation. */ static void je_iterate_small(arena_run_t *run, void (*callback)(uintptr_t ptr, size_t size, void* arg), void* arg) { szind_t binind; const arena_bin_info_t *bin_info; uint32_t regind; uintptr_t ptr; void *rpages; binind = run->binind; bin_info = &arena_bin_info[binind]; rpages = arena_miscelm_to_rpages(arena_run_to_miscelm(run)); ptr = (uintptr_t)rpages + bin_info->reg0_offset; for (regind = 0; regind < bin_info->nregs; regind++) { if (bitmap_get(run->bitmap, &bin_info->bitmap_info, regind)) { callback(ptr, bin_info->reg_size, arg); } ptr += bin_info->reg_interval; } }
static void test_bitmap_init(void) { size_t i; for (i = 1; i <= MAXBITS; i++) { bitmap_info_t binfo; bitmap_info_init(&binfo, i); { size_t j; bitmap_t *bitmap = malloc(sizeof(bitmap_t) * bitmap_info_ngroups(&binfo)); bitmap_init(bitmap, &binfo); for (j = 0; j < i; j++) assert(bitmap_get(bitmap, &binfo, j) == false); free(bitmap); } } }
int set_bitmap_gamma(TTF_Bitmap *bitmap, float gamma) { CHECKPTR(bitmap); if (gamma == 0) { return FAILURE; } float correction = 1 / gamma; for (int y = 0; y < bitmap->h; y++) { for (int x = 0; x < bitmap->w; x++) { uint32_t pixel = bitmap_get(bitmap, x, y); uint8_t *b = (uint8_t *)&pixel; b[0] = 255 * powf((b[0] / (float)255), correction); b[1] = 255 * powf((b[1] / (float)255), correction); b[2] = 255 * powf((b[2] / (float)255), correction); bitmap_set(bitmap, x, y, pixel); } } return SUCCESS; }
void free_pages(void *page, unsigned int count) { if (count == 0 || count > ram_pages - pages_reserved) { printf("free_pages: sorry, can't free %d pages (only %d RAM pages available)\n", count, ram_pages - pages_reserved); shutdown(); } void *end = page + count*PAGE_SIZE - 1; if (page < (void *)0xC0000000 || end < (void *)0xC0000000) { printf("free_pages: virtual address %p through %p is too low to have come from alloc_pages\n", page, end); shutdown(); } unsigned int paddr = virtual_to_physical(page); if (paddr & 0xfff) { printf("free_pages: virtual address %p is not aligned properly\n", page); shutdown(); } unsigned int ppn = paddr / PAGE_SIZE; if (ppn < ram_start_page || ppn + count > ram_end_page) { printf("free_pages: virtual address %p is not mapped to RAM\n", page); shutdown(); } if (ppn < ram_start_page + pages_reserved) { printf("free_pages: virtual address %p is reserved and should never be freed\n", page); shutdown(); } while (count > 0) { int i = (ppn - ram_start_page - pages_reserved); if (bitmap_get(page_alloc_bitmap, i) == 0) { printf("free_pages: virtual address %p is already free\n", page); shutdown(); } bitmap_set(page_alloc_bitmap, i, 0); count--; page += PAGE_SIZE; ppn++; } }
TEST_END TEST_BEGIN(test_bitmap_init) { size_t i; for (i = 1; i <= BITMAP_MAXBITS; i++) { bitmap_info_t binfo; bitmap_info_init(&binfo, i); { size_t j; bitmap_t *bitmap = (bitmap_t *)malloc( bitmap_size(&binfo)); bitmap_init(bitmap, &binfo); for (j = 0; j < i; j++) { assert_false(bitmap_get(bitmap, &binfo, j), "Bit should be unset"); } free(bitmap); } } }
/** * Frees given page. Given page should be reserved, but not staticly * reserved. * * @param phys_addr Page to be freed. */ void physmem_freeblock(void *Ptr) { interrupt_status_t intr_status; int i; physaddr_t phys_addr = (physaddr_t)Ptr; i = phys_addr / PAGE_SIZE; /* A page allocated by stalloc should not be freed. */ KERNEL_ASSERT(i >= physmem_static_end); intr_status = _interrupt_disable(); spinlock_acquire(&physmem_slock); /* Check that the page was reserved. */ KERNEL_ASSERT(bitmap_get(physmem_free_pages, i) == 1); bitmap_set(physmem_free_pages, i, 0); physmem_num_free_pages++; spinlock_release(&physmem_slock); _interrupt_set_state(intr_status); }
void draw_full(Layer *layer, GContext *ctx) { unsigned int i; int realdaymin; #ifdef FORCESTARTAT APP_LOG(APP_LOG_LEVEL_DEBUG, "%d", daymin); #endif realdaymin = daymin - (SCREENWIDTH / 2); if(realdaymin < 0) realdaymin = MINSINDAY + realdaymin; graphics_context_set_compositing_mode(ctx, GCompOpSet); update_window_color(); #ifdef PROFILING int start, startms, end, endms; start = time(NULL); startms = time_ms(NULL, NULL); #endif // fill the screen with background graphic for(i = 0; i < SCREENWIDTH / 32 + 1; i++) { graphics_draw_bitmap_in_rect(ctx, bg, GRect(i * 32, 0, 32, 101)); } if(realdaymin <= MINSINDAY - SCREENWIDTH) { for(i = 0; i < SPRITECOUNT; i++) { // Consider sprites that wrap around past the end of a day. if(spritelist[i].rect.origin.x + spritelist[i].rect.size.w > MINSINDAY) { if(RANGE_TEST(realdaymin, realdaymin + SCREENWIDTH, spritelist[i].rect.origin.x - MINSINDAY, spritelist[i].rect.origin.x - MINSINDAY + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x - MINSINDAY - realdaymin, spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } } if(RANGE_TEST(realdaymin, realdaymin + SCREENWIDTH, spritelist[i].rect.origin.x, spritelist[i].rect.origin.x + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x - realdaymin, spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } } } else { for(i = 0; i < SPRITECOUNT; i++) { if(RANGE_TEST(realdaymin, MINSINDAY, spritelist[i].rect.origin.x, spritelist[i].rect.origin.x + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x - realdaymin, spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } else if (RANGE_TEST(0, SCREENWIDTH - (MINSINDAY - realdaymin), spritelist[i].rect.origin.x, spritelist[i].rect.origin.x + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x + (MINSINDAY - realdaymin), spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } } } graphics_draw_bitmap_in_rect(ctx, pointergfx, GRect(SCREENWIDTH / 2 - 6, 0, 13, 7)); // Status bar stuff graphics_draw_bitmap_in_rect(ctx, status, GRect(2, SCREENHEIGHT - 15, 66, 13)); graphics_draw_bitmap_in_rect(ctx, weekdays[weekday], GRect(4, SCREENHEIGHT - 13, 23, 9)); if(day > 9) { graphics_draw_bitmap_in_rect(ctx, numbers[day / 10], GRect(31, SCREENHEIGHT - 13, 7, 9)); } graphics_draw_bitmap_in_rect(ctx, numbers[day % 10], GRect(39, SCREENHEIGHT - 13, 7, 9)); if(battlife <= BATT_MED_LEVEL) { graphics_draw_bitmap_in_rect(ctx, batteries[0], GRect(49, SCREENHEIGHT - 13, 7, 9)); } else if(battlife <= BATT_HIGH_LEVEL) { graphics_draw_bitmap_in_rect(ctx, batteries[1], GRect(49, SCREENHEIGHT - 13, 7, 9)); } else if(battlife <= BATT_FULL_LEVEL) { graphics_draw_bitmap_in_rect(ctx, batteries[2], GRect(49, SCREENHEIGHT - 13, 7, 9)); } else { graphics_draw_bitmap_in_rect(ctx, batteries[3], GRect(49, SCREENHEIGHT - 13, 7, 9)); } if(btstatus) { graphics_draw_bitmap_in_rect(ctx, bluetooth, GRect(59, SCREENHEIGHT - 13, 7, 9)); } #ifdef PROFILING // before bitmaps_clean() to get peak heap usage. APP_LOG(APP_LOG_LEVEL_DEBUG, "Heap free after draw: %d", heap_bytes_free()); #endif bitmaps_clean(); #ifdef PROFILING endms = time_ms(NULL, NULL); end = time(NULL); APP_LOG(APP_LOG_LEVEL_DEBUG, "Draw took %d milliseconds", ((end * 1000 + endms) - (start * 1000 + startms))); #endif }
void text_editor(struct bitmap *keys, struct FLAGS *flags, key_t msgq_key){ { //0->1 count int i, c=0; for(i=0;i<9;i++){ if(!flags->key[i] && bitmap_get(keys, IN_BUTTON_FPGA_1 + i)){ c++; flags->key[i] = true; } } if(c>0){ // COUNTER print printf("%d\n", c); flags->typed += c; { // 1000 msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_7SEGMENTS_FPGA_1; i.mbool = true; i.mvalue = flags->typed / 1000; msgq_send(msgq_key, &i); } { // 100 msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_7SEGMENTS_FPGA_2; i.mbool = true; i.mvalue = (flags->typed / 100) % 10; msgq_send(msgq_key, &i); } { // 10 msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_7SEGMENTS_FPGA_3; i.mbool = true; i.mvalue = (flags->typed / 10) % 10; msgq_send(msgq_key, &i); } { // 1 msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_7SEGMENTS_FPGA_4; i.mbool = true; i.mvalue = flags->typed % 10; msgq_send(msgq_key, &i); } } } { //1->0 wording bool pressed[9]; int j, d=0; for(j=0;j<9;j++) pressed[j] = false; for(j=0;j<9;j++){ if(flags->key[j] && !bitmap_get(keys, IN_BUTTON_FPGA_1 + j)){ d++; flags->key[j] = false; pressed[j] = true; }else if(flags->key[j] && bitmap_get(keys, IN_BUTTON_FPGA_1 + j)){ d++; //pressed[j] = true; } } { // pressed rules; #define P(i) bitmap_get(keys, IN_BUTTON_FPGA_1 + (i) - 1) if(P(2) && P(3)){ // custom mode! // TODO bitmap_set(keys, IN_BUTTON_FPGA_2, false); bitmap_set(keys, IN_BUTTON_FPGA_3, false); }else if(P(4) && P(5)){ // clear + counter save. text_editor_init(keys, flags, msgq_key); bitmap_set(keys, IN_BUTTON_FPGA_4, false); bitmap_set(keys, IN_BUTTON_FPGA_5, false); }else if(P(5) && P(6)){ // A<->1 flags->flag_a_1 = !flags->flag_a_1; flags->last_letter = -1; flags->last_letter_times = 0; if(flags->flag_a_1){ // print A msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_DOTMATRIX_FPGA_A; i.mbool = true; msgq_send(msgq_key, &i); }else{ // print 1 msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_DOTMATRIX_FPGA_1; i.mbool = true; msgq_send(msgq_key, &i); } bitmap_set(keys, IN_BUTTON_FPGA_5, false); bitmap_set(keys, IN_BUTTON_FPGA_6, false); }else if(P(8) && P(9)){ // shutdown // TODO { msg_pack t; t.mtype = MSG_TO_PROCESS; t.mdata = IN_SWITCH_GPIO_SELECT; msgq_send(msgq_key, &t); } bitmap_set(keys, IN_BUTTON_FPGA_8, false); bitmap_set(keys, IN_BUTTON_FPGA_9, false); }else if(d==1){ // 1 button if(flags->flag_a_1){ // A char letr[9][3] = {{'.', 'Q', 'Z'}, {'A', 'B', 'C'}, {'D', 'E', 'F'}, {'G', 'H', 'I'}, {'J', 'K', 'L'}, {'M', 'N', 'O'}, {'P', 'R', 'S'}, {'T', 'U', 'V'}, {'W', 'X', 'Y'}}; for(j=0;j<9;j++){ if(pressed[j]){ // j //bitmap_set(keys, IN_BUTTON_FPGA_1 + j, false); if(flags->last_letter == j){ // jj if(flags->last_letter_times == 3){ flags->last_letter_times = 1; { msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_LCD_FPGA_CHAR; i.mbool = true; // XXX no overwrite; i.mvalue = letr[j][flags->last_letter_times - 1]; msgq_send(msgq_key, &i); } }else{ flags->last_letter_times++; { msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_LCD_FPGA_CHAR; i.mbool = false; // XXX overwrite; i.mvalue = letr[j][flags->last_letter_times - 1]; msgq_send(msgq_key, &i); } } }else{ flags->last_letter = j; flags->last_letter_times = 1; { msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_LCD_FPGA_CHAR; i.mbool = true; // XXX no overwrite; i.mvalue = letr[j][flags->last_letter_times - 1]; msgq_send(msgq_key, &i); } } break; } } }else if(!flags->flag_a_1){ // 1 for(j=0;j<9;j++){ if(pressed[j]){ //bitmap_set(keys, IN_BUTTON_FPGA_1 + j, false); msg_pack i; i.mtype = MSG_TO_OUTPUT; i.mdata = OUT_LCD_FPGA_CHAR; i.mbool = true; // XXX no overwrite; i.mvalue = '1' + j; msgq_send(msgq_key, &i); break; } } } } } } }