diff --git a/src/components/gpu.c b/src/components/gpu.c index 02d7609..0885638 100644 --- a/src/components/gpu.c +++ b/src/components/gpu.c @@ -431,6 +431,10 @@ void nni_gpu_maxDepth(nni_gpu *gpu, void *_, nn_component *component, nn_compute nn_return(computer, nn_values_integer(gpu->currentScreen->maxDepth)); } +void nni_gpu_useless(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) { + nn_return_boolean(computer, true); +} + void nn_loadGraphicsCardTable(nn_universe *universe) { nn_componentTable *gpuTable = nn_newComponentTable(nn_getAllocator(universe), "gpu", NULL, NULL, (nn_componentDestructor *)nni_gpuDeinit); nn_storeUserdata(universe, "NN:GPU", gpuTable); @@ -456,6 +460,8 @@ void nn_loadGraphicsCardTable(nn_universe *universe) { nn_defineMethod(gpuTable, "fill", (nn_componentMethod *)nni_gpu_fill, "fill(x: integer, y: integer, w: integer, h: integer, s: string)"); nn_defineMethod(gpuTable, "copy", (nn_componentMethod *)nni_gpu_copy, "copy(x: integer, y: integer, w: integer, h: integer, tx: integer, ty: integer) - Copies stuff"); nn_defineMethod(gpuTable, "getViewport", (nn_componentMethod *)nni_gpu_getViewport, "getViewport(): integer, integer - Gets the current viewport resolution"); + + nn_defineMethod(gpuTable, "freeAllBuffers", (nn_componentMethod *)nni_gpu_useless, "dummy for now"); } nn_component *nn_addGPU(nn_computer *computer, nn_address address, int slot, nn_gpuControl *control) { diff --git a/src/components/loopbackModem.c b/src/components/loopbackModem.c index 07baa48..7f89f74 100644 --- a/src/components/loopbackModem.c +++ b/src/components/loopbackModem.c @@ -86,6 +86,26 @@ nn_bool_t nn_loopModem_send(nn_modemLoop *loop, nn_address address, nn_size_t po return true; } +double nn_loopModem_getStrength(nn_modemLoop *loop, nn_errorbuf_t err) { + return loop->strength; +} + +double nn_loopModem_setStrength(nn_modemLoop *loop, double n, nn_errorbuf_t err) { + loop->strength = n; + return n; +} + +nn_size_t nn_loopModem_getWakeMessage(nn_modemLoop *loop, char *msg, nn_errorbuf_t err) { + nn_memcpy(msg, loop->wakeup, loop->wakeupLen); + return loop->wakeupLen; +} + +nn_size_t nn_loopModem_setWakeMessage(nn_modemLoop *loop, const char *msg, nn_size_t msglen, nn_bool_t fuzzy, nn_errorbuf_t err) { + loop->wakeupLen = msglen; + nn_memcpy(loop->wakeup, msg, loop->wakeupLen); + return loop->wakeupLen; +} + nn_modem *nn_debugLoopbackModem(nn_Context *context, nn_debugLoopbackNetworkOpts opts, nn_networkControl control) { opts.address = nn_strdup(&context->allocator, opts.address); nn_modemLoop *m = nn_alloc(&context->allocator, sizeof(nn_modemLoop)); @@ -114,6 +134,11 @@ nn_modem *nn_debugLoopbackModem(nn_Context *context, nn_debugLoopbackNetworkOpts .send = (void *)nn_loopModem_send, .maxStrength = opts.maxStrength, + .getStrength = (void *)nn_loopModem_getStrength, + .setStrength = (void *)nn_loopModem_setStrength, + + .setWakeMessage = (void *)nn_loopModem_setWakeMessage, + .getWakeMessage = (void *)nn_loopModem_getWakeMessage, }; return nn_newModem(context, table, control); } diff --git a/src/components/modem.c b/src/components/modem.c index ead414e..005e839 100644 --- a/src/components/modem.c +++ b/src/components/modem.c @@ -65,7 +65,42 @@ static nn_bool_t nni_modem_wirelessOnly(nn_modem *modem, void *_) { } static void nni_modem_maxStrength(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) { - nn_return_integer(computer, modem->table.maxStrength); + nn_return_number(computer, modem->table.maxStrength); +} + +static void nni_modem_getStrength(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) { + nn_errorbuf_t err = ""; + + nn_lock(&modem->ctx, modem->lock); + double n = modem->table.getStrength(modem->table.userdata, err); + nn_unlock(&modem->ctx, modem->lock); + + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + + nn_return_number(computer, n); +} + +static void nni_modem_setStrength(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) { + double n = nn_toNumber(nn_getArgument(computer, 0)); + + if(n < 0) n = 0; + if(n > modem->table.maxStrength) n = modem->table.maxStrength; + + nn_errorbuf_t err = ""; + + nn_lock(&modem->ctx, modem->lock); + n = modem->table.setStrength(modem->table.userdata, n, err); + nn_unlock(&modem->ctx, modem->lock); + + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + + nn_return_number(computer, n); } static nn_bool_t nni_modem_validSendPort(nn_intptr_t port) { @@ -216,6 +251,51 @@ static void nni_modem_broadcast(nn_modem *modem, void *_, nn_component *componen nn_return_boolean(computer, res); } +static void nni_modem_getWake(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) { + char msg[NN_MAX_WAKEUPMSG]; + nn_errorbuf_t err = ""; + + nn_lock(&modem->ctx, modem->lock); + nn_size_t len = modem->table.getWakeMessage(modem->table.userdata, msg, err); + nn_unlock(&modem->ctx, modem->lock); + + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + + nn_return_string(computer, msg, len); +} + +static void nni_modem_setWake(nn_modem *modem, void *_, nn_component *component, nn_computer *computer) { + nn_size_t buflen; + const char *buf = nn_toString(nn_getArgument(computer, 0), &buflen); + + if(buf == NULL) { + nn_setCError(computer, "invalid wake message"); + return; + } + + if(buflen > NN_MAX_WAKEUPMSG) { + buflen = NN_MAX_WAKEUPMSG; + } + + nn_bool_t fuzzy = nn_toBoolean(nn_getArgument(computer, 1)); // nil is false + + nn_errorbuf_t err = ""; + + nn_lock(&modem->ctx, modem->lock); + buflen = modem->table.setWakeMessage(modem->table.userdata, buf, buflen, fuzzy, err); + nn_unlock(&modem->ctx, modem->lock); + + if(!nn_error_isEmpty(err)) { + nn_setError(computer, err); + return; + } + + nn_return_string(computer, buf, buflen); +} + void nn_loadModemTable(nn_universe *universe) { nn_componentTable *modemTable = nn_newComponentTable(nn_getAllocator(universe), "modem", NULL, NULL, (nn_componentDestructor *)nn_modem_destroy); nn_storeUserdata(universe, "NN:MODEM", modemTable); @@ -231,9 +311,17 @@ void nn_loadModemTable(nn_universe *universe) { nn_defineMethod(modemTable, "getPorts", (nn_componentMethod *)nni_modem_getPorts, "close([port: integer]): boolean - Closes a port, or nil for all ports"); nn_defineMethod(modemTable, "send", (nn_componentMethod *)nni_modem_send, "send(address: string, port: integer, ...): boolean - Sends a message to the specified address at the given port. It returns whether the message was sent, not received"); nn_defineMethod(modemTable, "broadcast", (nn_componentMethod *)nni_modem_broadcast, "broadcast(port: integer, ...): boolean - Broadcasts a message at the given port. It returns whether the message was sent, not received"); + nn_defineMethod(modemTable, "setWakeMessage", (nn_componentMethod *)nni_modem_setWake, "setWakeMessage(msg: string[, fuzzy: boolean]): string - Sets the wake-up message. This will be compared with the first value of modem messages to turn on computers. Set it to nothing to disable this functionality."); + nn_defineMethod(modemTable, "getWakeMessage", (nn_componentMethod *)nni_modem_getWake, "getWakeMessage(): string - Returns the current wake-up message"); // wireless stuff - method = nn_defineMethod(modemTable, "maxStrength", (nn_componentMethod *)nni_modem_maxStrength, "maxStrength(): integer - Returns the maximum strength of the device"); + method = nn_defineMethod(modemTable, "maxStrength", (nn_componentMethod *)nni_modem_maxStrength, "maxStrength(): number - Returns the maximum strength of the device"); + nn_method_setCondition(method, (nn_componentMethodCondition_t *)nni_modem_wirelessOnly); + + method = nn_defineMethod(modemTable, "getStrength", (nn_componentMethod *)nni_modem_getStrength, "getStrength(): number - Returns the current strength of the device"); + nn_method_setCondition(method, (nn_componentMethodCondition_t *)nni_modem_wirelessOnly); + + method = nn_defineMethod(modemTable, "setStrength", (nn_componentMethod *)nni_modem_setStrength, "setStrength(value: number): number - Returns the current strength of the device"); nn_method_setCondition(method, (nn_componentMethodCondition_t *)nni_modem_wirelessOnly); } diff --git a/src/emulator.c b/src/emulator.c index 8ef4c3e..f71b476 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -154,13 +154,11 @@ nn_bool_t ne_eeprom_set(void *addr, const char *buf, size_t len, nn_errorbuf_t e } nn_size_t ne_eeprom_getData(void *_, char *buf, nn_errorbuf_t err) { - nn_error_write(err, "unsupported"); return 0; } nn_bool_t ne_eeprom_setData(void *_, const char *buf, size_t len, nn_errorbuf_t err) { - nn_error_write(err, "unsupported"); - return false; + return true; } nn_bool_t ne_eeprom_isReadonly(void *userdata, nn_errorbuf_t err) { @@ -708,7 +706,7 @@ int main() { nn_drive *genericDrive = nn_volatileDrive(&ctx, vdriveOpts, vdriveCtrl); nn_addDrive(computer, NULL, 4, genericDrive); - int maxWidth = 80, maxHeight = 32; + int maxWidth = 160, maxHeight = 48; nn_screen *s = nn_newScreen(&ctx, maxWidth, maxHeight, 24, 16, 256); nn_setDepth(s, 4); // looks cool diff --git a/src/neonucleus.h b/src/neonucleus.h index 0155221..c1e2272 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -931,13 +931,13 @@ typedef struct nn_modemTable { nn_bool_t (*send)(void *userdata, nn_address address, nn_size_t port, nn_value *values, nn_size_t valueCount, nn_errorbuf_t err); // signal strength - nn_size_t maxStrength; - nn_size_t (*getStrength)(void *userdata, nn_errorbuf_t err); - nn_bool_t (*setStrength)(void *userdata, nn_size_t strength, nn_errorbuf_t err); + double maxStrength; + double (*getStrength)(void *userdata, nn_errorbuf_t err); + double (*setStrength)(void *userdata, double strength, nn_errorbuf_t err); // wake message - void (*getWakeMessage)(void *userdata, char *buf, nn_size_t *buflen); - nn_size_t (*setWakeMessage)(void *userdata, const char *buf, nn_size_t buflen, nn_bool_t fuzzy); + nn_size_t (*getWakeMessage)(void *userdata, char *buf, nn_errorbuf_t err); + nn_size_t (*setWakeMessage)(void *userdata, const char *buf, nn_size_t buflen, nn_bool_t fuzzy, nn_errorbuf_t err); } nn_modemTable; typedef struct nn_modem nn_modem; @@ -948,7 +948,7 @@ typedef struct nn_debugLoopbackNetworkOpts { nn_size_t maxValues; nn_size_t maxPacketSize; nn_size_t maxOpenPorts; - nn_size_t maxStrength; + double maxStrength; nn_bool_t isWireless; } nn_debugLoopbackNetworkOpts;