static void define_value(enum print_arg_type field_type, const char *ev_name, const char *field_name, const char *field_value, const char *field_str) { const char *handler_name = "define_flag_value"; PyObject *handler, *t, *retval; unsigned long long value; unsigned n = 0; if (field_type == PRINT_SYMBOL) handler_name = "define_symbolic_value"; t = PyTuple_New(4); if (!t) Py_FatalError("couldn't create Python tuple"); value = eval_flag(field_value); PyTuple_SetItem(t, n++, PyString_FromString(ev_name)); PyTuple_SetItem(t, n++, PyString_FromString(field_name)); PyTuple_SetItem(t, n++, PyInt_FromLong(value)); PyTuple_SetItem(t, n++, PyString_FromString(field_str)); handler = PyDict_GetItemString(main_dict, handler_name); if (handler && PyCallable_Check(handler)) { retval = PyObject_CallObject(handler, t); if (retval == NULL) handler_call_die(handler_name); } Py_DECREF(t); }
static void define_symbolic_value(const char *ev_name, const char *field_name, const char *field_value, const char *field_str) { unsigned long long value; dSP; value = eval_flag(field_value); ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(ev_name, 0))); XPUSHs(sv_2mortal(newSVpv(field_name, 0))); XPUSHs(sv_2mortal(newSVuv(value))); XPUSHs(sv_2mortal(newSVpv(field_str, 0))); PUTBACK; if (get_cv("main::define_symbolic_value", 0)) call_pv("main::define_symbolic_value", G_SCALAR); SPAGAIN; PUTBACK; FREETMPS; LEAVE; }
static void define_value(enum print_arg_type field_type, int id, const char *field_name, const char *field_value, const char *field_str) { const char *handler_name = (field_type == PRINT_SYMBOL) ? "define_symbol" : "define_flag"; unsigned long long value; value = eval_flag(field_value); fprintf(ofp, ",\n[\"%s\",%d,{\"field\":\"%s\",\"value\":%llu,\"name\":\"%s\"}]", handler_name, id, field_name, value, field_str); }
int main(int argc, char *argv[]) { if (eval_flag(argc,argv,"-h\0")) { printf("Usage: lold [-p PORT] [-D DELAY] [-d DEVICE]\n\n"); return EXIT_FAILURE; } delay = int_arg(eval_arg(argc, argv, "-D\0", NULL), DEF_DELAY); port = int_arg(eval_arg(argc, argv, "-p\0", NULL), DEF_LOLD_PORT); device = eval_arg(argc, argv, "-d\0", NULL); to_stdout = eval_flag(argc, argv, "--stdout\0"); if (!to_stdout && device==NULL) //no device provided? device = autodetect(); if (!device && !to_stdout) //no device found by autodetect? fprintf(stderr, "No serial USB device found! (Try -d flag?) Output to stdout.\n"); pthread_mutex_init(&imutex, NULL); //init mutex for interrupted flag pthread_mutex_init(&qmutex, NULL); //init mutex for queue //Start web server thread listening for clients sending stuff pthread_t serverThread; pthread_create(&serverThread, NULL, server_thread, NULL); pthread_detach(serverThread); //trap INT signal(SIGINT, sig_handler); LolTask *currtask = NULL; //task currently being executed //clean lolshield render_frame(device, EMPTY_FRAME); //loop outputting animation frames to device while (!shutting_down) { //do nothing if some client is streaming if (streaming) { sleep_ms(100); continue; } //New task arrived -> check stuff pthread_mutex_lock(&imutex); if (interrupted) { interrupted = 0; if (DEBUG) fprintf(stderr, "New task inserted!\n"); if (queue==NULL) exit(EXIT_FAILURE); //can not happen! pthread_mutex_lock(&qmutex); LolTask *first = (LolTask*)(queue->value); pthread_mutex_unlock(&qmutex); //new arrived has higher priority? cancel current ani if (currtask != NULL && first->pri > currtask->pri) { loltask_free(currtask); currtask = NULL; if (DEBUG) fprintf(stderr, "Ani cancelled\n"); } } pthread_mutex_unlock(&imutex); //load new task if neccessary if (currtask == NULL) { pthread_mutex_lock(&qmutex); currtask = lollist_shift(&queue); pthread_mutex_unlock(&qmutex); if (DEBUG) if (currtask != NULL) fprintf(stderr, "Ani start\n"); } //nothing in queue -> just wait if (currtask == NULL) { sleep_ms(delay); continue; } //animation delay sleep_ms(currtask->delay); //get next frame char *frame = lollist_shift(&(currtask->frames)); //current animation done? if (frame == NULL) { currtask = NULL; clean_tasks(); //remove aged tasks //render empty frame to clean lolshield -> breaks hardware text message //render_frame(device, EMPTY_FRAME); sleep_ms(delay); if (DEBUG) fprintf(stderr, "Ani done\n"); continue; } //render next frame render_frame(device, frame); free(frame); } if (DEBUG) fprintf(stderr, "Shutting down\n"); //shutting down render_frame(device, EMPTY_FRAME); //clean lolshield serialport_close(port); //close port pthread_cancel(serverThread); //kill server pthread_mutex_destroy(&qmutex); //uninit mutex pthread_mutex_destroy(&imutex); //uninit mutex close(svr_sock); //close server listening socket pthread_exit(NULL); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { if (argc==1) { printf("Usage: lolplay OPTIONS [-A|-P] [FILE (if not stdin)]\n"); printf(" lolplay OPTIONS [-m|-M] \"message\"\n"); printf(" lolplay OPTIONS -b VALUE\n"); printf(" lolplay OPTIONS -t\n"); printf("FLAGS:\n"); printf(" -h: lold host, default: %s\n", DEF_LOLD_HOST); printf(" -p: lold port, default: %i\n", DEF_LOLD_PORT); printf("\n"); printf(" -D: Frame delay (20-1000), default: %i\n", DEF_DELAY); printf(" -T: TTL in sec (0-600), default: %i\n", DEF_TTL); printf(" -C: Channel/Priority (>=0), default: %i\n", DEF_PRI); printf("\n"); printf(" -A: File is in AsciiFrame format (monochrome)\n"); printf(" -P: File is PDE sketch file from Lol Shield Theatre Homepage\n"); printf(" -R: File is raw animation data (as sent to sketch)\n"); printf("\n"); printf(" -m: Send scrolling text message (pre-rendered)\n"); printf(" -M: Send scrolling text message (rendered on Lol Shield)\n"); printf("\n"); printf(" -b: Set maximum brightness (1-7)\n"); printf(" -t: Toggle Lolshield mode (loop ROM or pass through mode)\n"); printf("\n"); printf(" -B: with '-[mAPR]' - burn this animation to Lolshield ROM\n"); printf(" -g: with '-A' - render in grayscale (not with '-B' !)\n"); printf(" -o: added to any command - output raw frames to stdout, no sending\n"); printf("\n"); exit(EXIT_FAILURE); } int del = int_arg(eval_arg(argc, argv, "-D\0", NULL), DEF_DELAY); int ttl = int_arg(eval_arg(argc, argv, "-T\0", NULL), DEF_TTL); int pri = int_arg(eval_arg(argc, argv, "-C\0", NULL), DEF_PRI); int port = int_arg(eval_arg(argc, argv, "-p\0", NULL), DEF_LOLD_PORT); char *host = eval_arg(argc, argv, "-h\0", DEF_LOLD_HOST); int bflag = eval_flag(argc, argv, "-b\0"); int gflag = eval_flag(argc, argv, "-g\0"); int oflag = eval_flag(argc, argv, "-o\0"); int tflag = eval_flag(argc, argv, "-t\0"); int burnFlag = eval_flag(argc, argv, "-B\0"); int mFlag = eval_flag(argc, argv, "-m\0"); int MFlag = eval_flag(argc, argv, "-M\0"); int aniType = 0; //Initialize loltask LolTask *task = loltask_new(); task->delay = burnFlag ? 100 : del; task->ttl = ttl; task->pri = pri; if (tflag) { //just toggle char *frame = malloc(100*sizeof(char)); frame[0] = '\0'; snprintf(frame, 100, "16384,0,0,0,0,0,0,0,0"); task->frames = lollist_add(task->frames, frame); goto send; } else if (bflag) { //just set brightness char *val = eval_arg(argc, argv, "-b\0", NULL); char *frame = malloc(100*sizeof(char)); frame[0] = '\0'; snprintf(frame, 100, "16387,%s",val); task->frames = lollist_add(task->frames, frame); goto send; } if (mFlag) { //software text message char *msg = eval_arg(argc, argv, "-m\0", NULL); if (msg == NULL) { printf("No message passed!\n"); exit(EXIT_FAILURE); } //create lolfactory, generate banner LolFactory *fac = lolfac_new(); int len = strlen(msg); lolfac_banner(fac, len, msg); //free lolfactory rescuing frames LolList *frames = fac->frames; fac->frames = NULL; lolfac_free(fac); //fill loltask with frames task->frames = frames; } else if (MFlag) { char *msg = eval_arg(argc, argv, "-M\0", NULL); char *frame = malloc(100*sizeof(char)); frame[0] = '\0'; snprintf(frame, BUFSIZE-1, "16385,%i,0,%s", del, msg); task->frames = lollist_add(task->frames, frame); } else { //animation file //open file char *filename = argv[argc-1]; FILE *fp = fopen(filename, "r"); if (fp == NULL) { // exit(EXIT_FAILURE); //failed opening file fp = stdin; //use standard input if no file given } char *line = NULL; size_t len = 0; ssize_t read; //read lines LolList *lines = NULL; while ((read = getline(&line, &len, fp)) != -1) { lines = lollist_add(lines, line); line = NULL; } if (eval_flag(argc, argv, "-R\0")) //raw data aniType = 1; if (eval_flag(argc, argv, "-A\0")) //ascii frames aniType = 2; else if (eval_flag(argc, argv, "-P\0")) //PDE sketch aniType = 3; if (aniType==1) { //raw LolList *curr = lines; while (curr!=NULL) { char *str = curr->value; len = strlen(str); if (str[len-1] == '\n') str[len-1] = '\0'; curr = curr->next; } task->frames = lines; } else if (aniType==2) { //ascii task->frames = ascii2frames(lines, gflag); } else if (aniType==3) { //pde task->delay = get_delay_from_pde(lines); task->frames = pde2frames(lines); } else { printf("No valid type selected!\n"); exit(EXIT_FAILURE); } } //burn flag set if (burnFlag) { if (gflag) { printf("Can not burn grayscale animation!\n"); exit(EXIT_FAILURE); } //check message length int cnt = 0; LolList *curr = task->frames; while (curr!=NULL) { curr = curr->next; cnt++; if (cnt>56) { printf("Message too long to store (max. frames: 56)!\n"); exit(EXIT_FAILURE); } } //TODO: check invalid stuff which can not be recorded (all non-regular frames) //prepend and append recording signal commands (start/stop recording) char *frame = malloc(100*sizeof(char)); snprintf(frame, 100, "16384,1,%i,0,0,0,0,0,0", del); lollist_insert(&task->frames, task->frames, frame); frame = malloc(100*sizeof(char)); snprintf(frame, 100, "16384,0,0,0,0,0,0,0,0"); lollist_add(task->frames, frame); } send: //append clearing frame if animation from file if (aniType) { char *frame = malloc(100*sizeof(char)); snprintf(frame, 100, "0,0,0,0,0,0,0,0,0"); lollist_add(task->frames, frame); } //output flag set - no sending, but output if (oflag) { LolList *curr = task->frames; while (curr!=NULL) { printf("%s\n", (char*)curr->value); curr = curr->next; } loltask_free(task); return EXIT_SUCCESS; } //try to send if (!loltask_send(host, port, task)) //error sending exit(EXIT_FAILURE); //done loltask_free(task); return EXIT_SUCCESS; }