int main(int argc, char** argv) { struct arg_arr* aarr; struct arcan_shmif_cont cont = arcan_shmif_open( SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr); arcan_event ev; bool running = true; arcan_shmif_resize(&cont, 320, 200); /* fill with red and transfer */ for (size_t row = 0; row < cont.addr->h; row++) for (size_t col = 0; col < cont.addr->w; col++) cont.vidp[ row * cont.addr->w + col ] = RGBA(255, 0, 0, 255); arcan_shmif_signal(&cont, SHMIF_SIGVID); while (running && arcan_shmif_wait(&cont, &ev)){ if (ev.category == EVENT_TARGET) switch (ev.tgt.kind){ case TARGET_COMMAND_EXIT: running = false; default: break; } } return EXIT_SUCCESS; }
/* * Build the output buffer and push/synch to an external recipient, * taking mapping function, alpha population functions, and timing- * related metadata. */ static void ch_step(struct rwstat_ch* ch) { struct rwstat_ch_priv* chp = ch->priv; struct arcan_event outev = { .category = EVENT_EXTERNAL, .ext.kind = EVENT_EXTERNAL_FRAMESTATUS, .ext.framestatus.framenumber = ch->priv->cnt_local, .ext.framestatus.pts = ch->priv->cnt_total, }; size_t ntw = chp->base * chp->base; ch->event(ch, &outev); /* * Notify about the packing mode active for this frame. This is * needed for the parent to be able to determine what each byte * corresponds to. */ if (chp->status_dirty){ outev.ext.kind = EVENT_EXTERNAL_STREAMINFO; outev.ext.streaminf.streamid = 0; outev.ext.streaminf.datakind = 0; outev.ext.streaminf.langid[0] = 'a' + chp->pack; outev.ext.streaminf.langid[1] = 'a' + chp->map; outev.ext.streaminf.langid[2] = 'a' + chp->pack_sz; chp->status_dirty = false; ch->event(ch, &outev); } if ( 1 == (chp->clock & (RW_CLK_SLIDE)) ) rebuild_hgram(chp); if (chp->amode == RW_ALPHA_ENTBASE) update_entalpha(chp, chp->ent_base); else if (chp->amode == RW_ALPHA_PTN) update_ptnalpha(chp); for (size_t i = 0; i < chp->buf_sz; i += chp->pack_sz) pack_bytes(chp, &chp->buf[i], i / chp->pack_sz); chp->cont->addr->vpts = ch->priv->cnt_total; arcan_shmif_signal(chp->cont, SHMIF_SIGVID); chp->cnt_local = chp->cnt_total; /* non-sparse mappings require an output flush */ if (chp->map == MAP_TUPLE || chp->map == MAP_TUPLE_ACC){ shmif_pixel val = SHMIF_RGBA(0x00, 0x00, 0x00, 0xff); for (size_t i = 0; i < ntw; i++) chp->cont->vidp[i] = val; } } static void ch_event(struct rwstat_ch* ch, arcan_event* ev) { arcan_shmif_enqueue(ch->priv->cont, ev); }
static void update_frame(struct arcan_shmif_cont* shms, shmif_pixel val) { shmif_pixel* cptr = shms->vidp; int np = shms->addr->w * shms->addr->h; for (int i = 0; i < np; i++) *cptr++ = val; arcan_shmif_signal(shms, SHMIF_SIGVID); }
int main(int argc, char** argv) #endif { struct arg_arr* aarr; struct arcan_shmif_cont cont = arcan_shmif_open( SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr); arcan_event ev; bool running = true; arcan_shmif_resize(&cont, 640, 480); uint8_t step_r = 0; uint8_t step_g = 0; uint8_t step_b = 255; int frames = 0; while(running){ if (frames++ > 200){ printf("send resize\n"); arcan_shmif_resize(&cont, 128 + (rand() % 1024), 128 + (rand() % 1024)); printf("unlock resize\n"); frames = 0; } printf("frame(%zu, %zu)\n", cont.w, cont.h); for (size_t row = 0; row < cont.h; row++) for (size_t col = 0; col < cont.w; col++){ cont.vidp[ row * cont.addr->w + col ] = SHMIF_RGBA(step_r, step_g, step_b, 0xff); step_r++; step_g += step_r == 255; step_b += step_g == 255; } arcan_shmif_signal(&cont, SHMIF_SIGVID); int rv; while ( (rv = arcan_shmif_poll(&cont, &ev)) == 1){ if (ev.category == EVENT_TARGET) switch (ev.tgt.kind){ case TARGET_COMMAND_EXIT: running = false; break; default: break; } } } #ifndef ENABLE_FSRV_AVFEED return EXIT_SUCCESS; #endif }
static void process_event(struct senseye_cont* cont, arcan_event* ev) { if (ev->category == EVENT_TARGET){ if (ev->tgt.kind == TARGET_COMMAND_STEPFRAME){ if (cont->refresh(cont, cont->priv->cont.vidp, cont->priv->cont.addr->w, cont->priv->cont.addr->h)){ arcan_shmif_signal(&cont->priv->cont, SHMIF_SIGVID); } } } cont->dispatch(cont, ev); }
int main(int argc, char** argv) #endif { struct arg_arr* aarr; struct arcan_shmif_cont cont = arcan_shmif_open( SEGID_APPLICATION, SHMIF_ACQUIRE_FATALFAIL, &aarr); arcan_shmif_signal(&cont, SHMIF_SIGVID); while (1){ arcan_shmif_resize_ext(&cont, cont.w, cont.h, (struct shmif_resize_ext){ .meta = SHMIF_META_CM }); if (arcan_shmif_substruct(&cont, SHMIF_META_CM).cramp) break; printf("no gamma, retrying in 1s\n"); sleep(1); }
static void* aprod(void* data) { struct arcan_shmif_cont* cont = data; size_t bps = ARCAN_SHMIF_ACHANNELS * sizeof(shmif_asample); while (1){ size_t nsamp = (cont->abufsize - cont->abufused) / (bps * 2); float stepv = 2.0 * 3.14 * ((5 * tones[ti]) / (float)cont->samplerate); for (size_t b = 0; b < cont->abuf_cnt; b++){ for (size_t i = 0; i < nsamp; i++){ cont->audp[i*2+0] = 32767.0 * sinf(pos); cont->audp[i*2+1] = 32767.0 * sinf(pos); pos += stepv; } cont->abufused = nsamp * bps; arcan_shmif_signal(cont, SHMIF_SIGAUD); } } return NULL; }
static void ch_damage(struct rwstat_ch* ch, uint8_t val, bool rand, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { struct rwstat_ch_priv* chp = ch->priv; struct arcan_shmif_cont* cont = chp->cont; /* useless in this setting */ if (chp->map == MAP_TUPLE || chp->map == MAP_TUPLE_ACC) return; if (y2 > cont->h || x2 > cont->w) return; for (size_t y = y1; y < y2; y++) for (size_t x = x1; x < x2; x++) cont->vidp[y*chp->cont->pitch+x] = pack_byte(val, rand, chp->pack); /* don't increment the counter, we stay at the same position etc. * just send the new damaged buffer. If we want to do fault-injection, * it'll need to be on the sensor- level */ arcan_shmif_signal(chp->cont, SHMIF_SIGVID); }
int main(int argc, char** argv) { int id = SEGID_APPLICATION; struct arg_arr* aarr; if (argc > 1){ if (strcmp(argv[1], "-game") == 0) id = SEGID_GAME; else if (strcmp(argv[1], "-terminal") == 0) id = SEGID_TERMINAL; else if (strcmp(argv[1], "-vm") == 0) id = SEGID_VM; else{ printf("usage: \n\tiodump to identify as normal application" "\n\tiodump -game to identify as game" "\n\tiodump -terminal to identify as terminal" "\n\tiodump -vm to identify as vm\n" ); return EXIT_FAILURE; } } struct arcan_shmif_cont cont = arcan_shmif_open( id, SHMIF_ACQUIRE_FATALFAIL, &aarr); printf("open\n"); arcan_event ev; /* just send garbage so the correct events are being propagated */ arcan_shmif_signal(&cont, SHMIF_SIGVID); printf("loop\n"); while (arcan_shmif_wait(&cont, &ev)){ if (ev.category == EVENT_TARGET){ switch (ev.tgt.kind){ case TARGET_COMMAND_BCHUNK_IN: printf("bchunk in\n"); dump_eof(ev.tgt.ioevs[0].iv); break; case TARGET_COMMAND_BCHUNK_OUT: printf("bchunk out\n"); write_eof(ev.tgt.ioevs[0].iv); break; case TARGET_COMMAND_MESSAGE: printf("message: %s\n", ev.tgt.message); break; case TARGET_COMMAND_EXIT: return EXIT_SUCCESS; default: printf("event: %s\n", arcan_shmif_eventstr(&ev, NULL, 0)); break; } } else if (ev.category == EVENT_IO){ switch (ev.io.datatype){ case EVENT_IDATATYPE_TRANSLATED: printf("(%s)[kbd(%d):%s] %d:mask=%d,sym:%d,code:%d,utf8:%s\n", ev.io.label, ev.io.devid, ev.io.input.translated.active ? "pressed" : "released", (int)ev.io.subid, (int)ev.io.input.translated.modifiers, (int)ev.io.input.translated.keysym, (int)ev.io.input.translated.scancode, ev.io.input.translated.utf8 ); break; case EVENT_IDATATYPE_ANALOG: printf("(%s)[%s(%d):%d] rel: %s, v(%d){%d, %d, %d, %d}\n", ev.io.label, ev.io.devkind == EVENT_IDEVKIND_MOUSE ? "mouse" : "analog", ev.io.devid, ev.io.subid, ev.io.input.analog.gotrel ? "yes" : "no", (int)ev.io.input.analog.nvalues, (int)ev.io.input.analog.axisval[0], (int)ev.io.input.analog.axisval[1], (int)ev.io.input.analog.axisval[2], (int)ev.io.input.analog.axisval[3] ); break; case EVENT_IDATATYPE_TOUCH: printf("(%s)[touch(%d)] %d: @%d,%d pressure: %f, size: %f\n", ev.io.label, ev.io.devid, ev.io.subid, (int) ev.io.input.touch.x, (int) ev.io.input.touch.y, ev.io.input.touch.pressure, ev.io.input.touch.size ); break; case EVENT_IDATATYPE_DIGITAL: if (ev.io.devkind == EVENT_IDEVKIND_MOUSE) printf("[mouse(%d):%d], %s:%s\n", ev.io.devid, ev.io.subid, msub_to_lbl(ev.io.subid), ev.io.input.digital.active ? "pressed" : "released" ); else printf("[digital(%d):%d], %s\n", ev.io.devid, ev.io.subid, ev.io.input.digital.active ? "pressed" : "released"); break; default: break; } } } return EXIT_SUCCESS; }
/* * Audio visualization, * just HANN -> FFT -> dB scale -> pack in 8-bit * could be used to push vocal input events to the * main engine with little extra work for singalong- * style controls */ static void generate_frame() { /* window size is twice the possible output, * since the FFT will be N/2 out */ const int smpl_wndw = AUD_VIS_HRES * 2; static float smplbuf[AUD_VIS_HRES * 2]; static kiss_fft_scalar fsmplbuf[AUD_VIS_HRES * 2]; static kiss_fft_cpx foutsmplbuf[AUD_VIS_HRES * 2]; static bool gotfft; static kiss_fftr_cfg kfft; if (!gotfft){ kfft = kiss_fftr_alloc(smpl_wndw, false, NULL, NULL); gotfft = true; } static int smplc; static double vptsc = 0; int16_t* basep = (int16_t*) decctx.audp; int counter = decctx.shmcont.addr->abufused; while (counter){ /* could've split the window up into * two functions and used the b and a channels * but little point atm. */ float lv = (*basep++) / 32767.0f; float rv = (*basep++) / 32767.0f; float smpl = (lv + rv) / 2.0f; smplbuf[smplc] = smpl; /* hann window float sample before FFT */ float winv = 0.5f * ( 1.0f - cosf(2.0 * M_PI * smplc / (float) smpl_wndw)); fsmplbuf[smplc] = smpl + 1.0 * winv; smplc++; counter -= 4; /* 4 bytes consumed */ if (smplc == smpl_wndw){ smplc = 0; uint8_t* base = decctx.vidp; kiss_fftr(kfft, fsmplbuf, foutsmplbuf); /* store FFT output in dB scale */ float low = 255.0f; float high = 0.0f; for (int j= 0; j < smpl_wndw / 2; j++) { float magnitude = sqrtf(foutsmplbuf[j].r * foutsmplbuf[j].r + foutsmplbuf[j].i * foutsmplbuf[j].i); fsmplbuf[j] = 10.0f * log10f(magnitude); if (fsmplbuf[j] < low) low = fsmplbuf[j]; if (fsmplbuf[j] > high) high = fsmplbuf[j]; } /* wasting a level just to get POT as the interface doesn't * support a 1D texture format */ for (int j=0; j<smpl_wndw / 2; j++){ *base++ = 0; *base++ = 0; *base++ = 0; *base++ = 0xff; } /* pack in output image, smooth two audio samples */ for (int j=0; j < smpl_wndw / 2; j++){ *base++ = (1.0f + ((smplbuf[j * 2] + smplbuf[j * 2 + 1]) / 2.0)) / 2.0 * 255.0; *base++ = (fsmplbuf[j] / high) * 255.0; *base++ = 0x00; *base++ = 0xff; } decctx.shmcont.addr->vpts = vptsc; arcan_shmif_signal(&decctx.shmcont, SHMIF_SIGVID); vptsc += 1000.0f / ( (double)(ARCAN_SHMPAGE_SAMPLERATE) / (double)smpl_wndw); } } arcan_shmif_signal(&decctx.shmcont, SHMIF_SIGVID); }