static EEL_xno img_SavePNG(EEL_vm *vm) { EEL_value *arg = vm->heap + vm->argv; int res; SDL_Surface *from; int comp = -1; /* Filename */ const char *fn = eel_v2s(arg); if(!fn) return EEL_XNEEDSTRING; /* Surface */ if(EEL_CLASS(arg + 1) != esdl_md.surface_cid) return EEL_XWRONGTYPE; from = o2ESDL_surface(arg[1].objref.v)->surface; /* Compression level */ if(vm->argc >= 3) { comp = eel_v2l(arg + 2); #if 0 if(comp < -1) return EEL_XLOWVALUE; if(comp > 9) return EEL_XHIGHVALUE; #endif } res = IMG_SavePNG(fn, from, comp); if(res) return EEL_XCANTWRITE; return 0; }
/*---------------------------------------------------------- IPaddress class ----------------------------------------------------------*/ static EEL_xno ipa_construct(EEL_vm *vm, EEL_types type, EEL_value *initv, int initc, EEL_value *result) { IPaddress *ipa; EEL_object *eo = eel_o_alloc(vm, sizeof(IPaddress), type); if(!eo) return EEL_XMEMORY; ipa = o2IPaddress(eo); switch(initc) { case 0: ipa->host = INADDR_NONE; ipa->port = 9999; break; case 1: if(EEL_TYPE(initv) == md.ipaddress_cid) { IPaddress *src = o2IPaddress(initv->objref.v); memcpy(ipa, src, sizeof(IPaddress)); } else { /* Create server socket */ if(SDLNet_ResolveHost(ipa, NULL, eel_v2l(initv)) != 0) { eel_o_free(eo); return EEL_XDEVICEOPEN; } } break; case 2: { const char *s; switch((EEL_classes)EEL_TYPE(initv)) { case EEL_CSTRING: case EEL_CDSTRING: s = eel_v2s(initv); default: s = NULL; } /* Connect as client */ if(SDLNet_ResolveHost(ipa, s, eel_v2l(initv + 1)) != 0) { eel_o_free(eo); return EEL_XDEVICEOPEN; } break; } default: eel_o_free(eo); return EEL_XARGUMENTS; } eel_o2v(result, eo); return 0; }
static EEL_xno ipa_setindex(EEL_object *eo, EEL_value *op1, EEL_value *op2) { IPaddress *ipa = o2IPaddress(eo); const char *is = eel_v2s(op1); int iv = eel_v2l(op2); if(!is) return EEL_XWRONGTYPE; if(strcmp(is, "host") == 0) ipa->host = iv; else if(strcmp(is, "port") == 0) ipa->port = iv; else return EEL_XWRONGINDEX; return 0; }
static EEL_xno ipa_getindex(EEL_object *eo, EEL_value *op1, EEL_value *op2) { IPaddress *ipa = o2IPaddress(eo); const char *is = eel_v2s(op1); if(!is) return EEL_XWRONGTYPE; if(strcmp(is, "host") == 0) op2->integer.v = ipa->host; else if(strcmp(is, "port") == 0) op2->integer.v = ipa->port; else return EEL_XWRONGINDEX; op2->type = EEL_TINTEGER; return 0; }
static EEL_xno img_Load(EEL_vm *vm) { EEL_xno x; SDL_Surface *to; const char *fn = eel_v2s(vm->heap + vm->argv); if(!fn) return EEL_XNEEDSTRING; to = IMG_Load(fn); if(!to) return EEL_XDEVICEERROR; x = eel_o_construct(vm, esdl_md.surface_cid, NULL, 0, vm->heap + vm->resv); if(x) { SDL_FreeSurface(to); return x; } o2ESDL_surface(vm->heap[vm->resv].objref.v)->surface = to; return 0; }
static EEL_xno n2s_getindex(EEL_object *eo, EEL_value *op1, EEL_value *op2) { EB_socket *ebs = o2EB_socket(eo); const char *is; if(!ebs->rs) return EEL_XDEVICECLOSED; is = eel_v2s(op1); if(!is) return EEL_XWRONGTYPE; if(strcmp(is, "index") == 0) op2->integer.v = ebs->rs->n2socket; else if(strcmp(is, "buffer") == 0) { if(ebs->rs->fifo.buffer) op2->integer.v = sfifo_space(&ebs->rs->fifo); else op2->integer.v = 0; } else return EEL_XWRONGINDEX; op2->type = EEL_TINTEGER; return 0; }
static EEL_xno n2_tcp_send(EEL_vm *vm) { EEL_value *args = vm->heap + vm->argv; EB_socket *ebs; int i, count = 0; if(EEL_TYPE(args) != md.net2_socket_cid) return EEL_XWRONGTYPE; ebs = o2EB_socket(args->objref.v); if(!ebs->rs) return EEL_XDEVICECLOSED; if(ebs->rs->status) return ebs->rs->status; for(i = 1; i < vm->argc; ++i) { void *buf; int bsize; EEL_value *v = args + i; switch((EEL_classes)EEL_TYPE(v)) { case EEL_CREAL: { int n; #if SDL_BYTEORDER == SDL_BIG_ENDIAN char lb[sizeof(EEL_real)]; *((EEL_real *)&lb) = v->real.v; #else union { EEL_real r; char c[sizeof(EEL_real)]; } cvt; char lb[sizeof(EEL_real)]; cvt.r = v->real.v; for(n = 0; n < sizeof(EEL_real); ++n) lb[n] = cvt.c[sizeof(EEL_real) - 1 - n]; #endif buf = &lb; bsize = sizeof(EEL_real); break; } case EEL_CINTEGER: { EEL_uint32 cvt; SDLNet_Write32(eel_v2l(v), &cvt); buf = &cvt; bsize = 4; break; } case EEL_CSTRING: case EEL_CDSTRING: { buf = (void *)eel_v2s(v); bsize = eel_length(v->objref.v); break; } default: return EEL_XARGUMENTS; } if(ebs->rs->sender) { /* Buffered, non-blocking */ if(sfifo_space(&ebs->rs->fifo) < bsize) return EEL_XBUFOVERFLOW; sfifo_write(&ebs->rs->fifo, buf, bsize); } else { /* Direct, blocking */ int n = NET2_TCPSend(ebs->rs->n2socket, buf, bsize); if(n < 0) return EEL_XDEVICEWRITE; } count += bsize; } eel_l2v(vm->heap + vm->resv, count); return 0; }
static EEL_xno n2s_construct(EEL_vm *vm, EEL_types type, EEL_value *initv, int initc, EEL_value *result) { REAL_EB_socket *rs; EB_socket *ebs; EEL_object *eo; rs = malloc(sizeof(REAL_EB_socket)); if(!rs) return EEL_XMEMORY; eo = eel_o_alloc(vm, sizeof(EB_socket), type); if(!eo) { free(rs); return EEL_XMEMORY; } ebs = o2EB_socket(eo); ebs->rs = rs; rs->pollperiod = 50; rs->sender = NULL; rs->fifo.buffer = NULL; rs->closed = 0; rs->status = EEL_XOK; switch(initc) { case 1: if(initv->type == EEL_TINTEGER) { rs->n2socket = eel_v2l(initv); if(rs->n2socket > NET2_MAX_SOCKETS) { eel_o_free(eo); return EEL_XHIGHINDEX; } } else { IPaddress *ipa; if(EEL_TYPE(initv) != md.ipaddress_cid) { eel_o_free(eo); return EEL_XWRONGTYPE; } ipa = o2IPaddress(initv->objref.v); rs->n2socket = NET2_TCPConnectToIP(ipa); if(rs->n2socket < 0) { eel_o_free(eo); return EEL_XDEVICEOPEN; } } break; case 2: rs->n2socket = NET2_TCPConnectTo(eel_v2s(initv), eel_v2l(initv + 1)); if(rs->n2socket < 0) { eel_o_free(eo); return EEL_XDEVICEOPEN; } break; default: eel_o_free(eo); return EEL_XARGUMENTS; } if(eb_sockets && (rs->n2socket >= 0)) eb_sockets[rs->n2socket] = eo; eel_o2v(result, eo); return 0; }