diff --git a/build.zig b/build.zig index ffa9c98..5570ae5 100644 --- a/build.zig +++ b/build.zig @@ -41,6 +41,8 @@ fn addEngineSources(b: *std.Build, opts: LibBuildOpts) *std.Build.Module { "src/components/keyboard.c", "src/components/modem.c", "src/components/loopbackModem.c", + "src/components/tunnel.c", + "src/components/loopbackTunnel.c", "src/components/diskDrive.c", }, .flags = &.{ diff --git a/src/components/gpu.c b/src/components/gpu.c index f542716..71c010a 100644 --- a/src/components/gpu.c +++ b/src/components/gpu.c @@ -604,15 +604,6 @@ void nni_gpu_getDepth(nni_gpu *gpu, void *_, nn_component *component, nn_compute nn_return(computer, nn_values_integer(gpu->currentScreen->depth)); } -const char *nn_depthName(int depth) { - if(depth == 1) return "OneBit"; - if(depth == 4) return "FourBit"; - if(depth == 8) return "EightBit"; - if(depth == 16) return "SixteenBit"; - if(depth == 24) return "TwentyFourBit"; - return NULL; -} - void nni_gpu_setDepth(nni_gpu *gpu, void *_, nn_component *component, nn_computer *computer) { if(gpu->currentScreen == NULL) return; int depth = nn_toInt(nn_getArgument(computer, 0)); diff --git a/src/components/loopbackTunnel.c b/src/components/loopbackTunnel.c new file mode 100644 index 0000000..e167b0d --- /dev/null +++ b/src/components/loopbackTunnel.c @@ -0,0 +1,7 @@ +#include "../neonucleus.h" + +nn_tunnel *nn_debugLoopbackTunnel(nn_Context *context, nn_debugLoopbackNetworkOpts opts, nn_networkControl control) { + nn_tunnelTable table = {}; + + return nn_newTunnel(context, table, control); +} diff --git a/src/components/screen.c b/src/components/screen.c index 1621bbc..c0ef794 100644 --- a/src/components/screen.c +++ b/src/components/screen.c @@ -423,11 +423,44 @@ static nn_bool_t nni_8bit_did = false; static int nni_4bitl_colors[16]; static nn_bool_t nni_4bitl_did = false; +const char *nn_depthName(int depth) { + if(depth == 1) return "OneBit"; + if(depth == 2) return "TwoBit"; + if(depth == 3) return "ThreeBit"; + if(depth == 4) return "FourBit"; + if(depth == 8) return "EightBit"; + if(depth == 16) return "SixteenBit"; + if(depth == 24) return "TwentyFourBit"; + return NULL; +} + int nn_mapDepth(int color, int depth, nn_bool_t legacy) { if(depth == 1) { if(color == 0) return nni_mcBlack; return nni_mcWhite; } + if(depth == 2) { + int palette[4] = { + 0x000000, + 0x444444, + 0x999999, + 0xFFFFFF, + }; + return nn_mapColor(color, palette, 4); + } + if(depth == 3) { + int palette[8] = { + 0x000000, + 0xFF0000, + 0x00FF00, + 0xFFFF00, + 0x0000FF, + 0xFF00FF, + 0x00FFFF, + 0xFFFFFF, + }; + return nn_mapColor(color, palette, 8); + } if(depth == 4) { if(legacy) { if(!nni_4bitl_did) { diff --git a/src/components/tunnel.c b/src/components/tunnel.c new file mode 100644 index 0000000..af41fb7 --- /dev/null +++ b/src/components/tunnel.c @@ -0,0 +1,53 @@ +#include "../neonucleus.h" + +typedef struct nn_tunnel { + nn_Context ctx; + nn_refc refc; + nn_guard *lock; + nn_tunnelTable table; + nn_networkControl ctrl; +} nn_tunnel; + +nn_tunnel *nn_newTunnel(nn_Context *context, nn_tunnelTable table, nn_networkControl control) { + nn_Alloc *a = &context->allocator; + + nn_tunnel *t = nn_alloc(a, sizeof(nn_tunnel)); + if(t == NULL) return NULL; + t->lock = nn_newGuard(context); + if(t->lock == NULL) { + nn_dealloc(a, t, sizeof(nn_tunnel)); + return NULL; + } + t->ctx = *context; + t->refc = 1; + t->table = table; + t->ctrl = control; + return t; +} + +nn_guard *nn_getTunnelLock(nn_tunnel *tunnel) { + return tunnel->lock; +} + +void nn_retainTunnel(nn_tunnel *tunnel) { + nn_incRef(&tunnel->refc); +} + +nn_bool_t nn_destroyTunnel(nn_tunnel *tunnel) { + if(!nn_decRef(&tunnel->refc)) return false; + return true; +} + +void nn_tunnel_destroy(void *_, nn_component *component, nn_tunnel *tunnel) { + nn_destroyTunnel(tunnel); +} + +void nn_loadTunnelTable(nn_universe *universe) { + nn_componentTable *tunnelTable = nn_newComponentTable(nn_getAllocator(universe), "tunnel", NULL, NULL, (nn_componentDestructor *)nn_tunnel_destroy); + nn_storeUserdata(universe, "NN:TUNNEL", tunnelTable); +} + +nn_component *nn_addTunnel(nn_computer *computer, nn_address address, int slot, nn_tunnel *tunnel) { + nn_componentTable *tunnelTable = nn_queryUserdata(nn_getUniverse(computer), "NN:TUNNEL"); + return nn_newComponent(computer, address, slot, tunnelTable, tunnel); +} diff --git a/src/emulator.c b/src/emulator.c index 720d53f..4c4fbd8 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -745,6 +745,25 @@ int main(int argc, char **argv) { nn_drive *genericDrive = nn_volatileDrive(&ctx, vdriveOpts, vdriveCtrl); nn_addDrive(computer, NULL, 4, genericDrive); + nn_networkControl netCtrl = { + .energyPerFullPacket = 0, + .heatPerFullPacket = 0, + .packetBytesPerTick = 16384, + }; + + nn_debugLoopbackNetworkOpts netOpts = { + .computer = computer, + .address = "loop", + .isWireless = false, + .maxValues = 8, + .maxOpenPorts = 64, + .maxPacketSize = 8192, + .maxStrength = 200, + }; + + nn_tunnel *t = nn_debugLoopbackTunnel(&ctx, netOpts, netCtrl); + nn_addTunnel(computer, NULL, -1, t); + int maxWidth = 80, maxHeight = 32; nn_screen *s = nn_newScreen(&ctx, maxWidth, maxHeight, 24, 16, 256); @@ -792,6 +811,8 @@ int main(int argc, char **argv) { double interval = 1.0/tps; double totalTime = 0; + SetTargetFPS(144); + while(true) { if(WindowShouldClose()) break; nn_setEnergyInfo(computer, 5000, 5000); diff --git a/src/universe.c b/src/universe.c index 958ebd7..d68be98 100644 --- a/src/universe.c +++ b/src/universe.c @@ -54,5 +54,6 @@ void nn_loadCoreComponentTables(nn_universe *universe) { nn_loadGraphicsCardTable(universe); nn_loadKeyboardTable(universe); nn_loadModemTable(universe); + nn_loadTunnelTable(universe); nn_loadDiskDriveTable(universe); }