progress on modem and basic todo
This commit is contained in:
5
TODO.md
5
TODO.md
@@ -1,9 +1,10 @@
|
|||||||
# For MVP functionality
|
# For MVP functionality
|
||||||
|
|
||||||
- NCL computer states, as computers that can be turned on/off/beep/etc.
|
- add brightness to screens, which power usage scales with, each different tier has a different max brightness as well
|
||||||
- write a tester OS, basically a menu with tests to run
|
- write a tester OS, basically a menu with tests to run
|
||||||
- tmpfs (rework the whole thing)
|
- finish tmpfs (rework the whole thing)
|
||||||
- device info
|
- device info
|
||||||
|
- finish `computer` components
|
||||||
- userdata support
|
- userdata support
|
||||||
|
|
||||||
# To re-evaluate
|
# To re-evaluate
|
||||||
|
|||||||
10
src/main.c
10
src/main.c
@@ -458,6 +458,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nn_Computer *c = nn_createComputer(u, NULL, "computer0", ramTotal, 256, 256);
|
nn_Computer *c = nn_createComputer(u, NULL, "computer0", ramTotal, 256, 256);
|
||||||
|
nn_Component *wrappedC = nn_wrapComputer(c);
|
||||||
if(showStats) {
|
if(showStats) {
|
||||||
// collects stats
|
// collects stats
|
||||||
nn_setEnergyHandler(c, NULL, ne_energy_accumulator);
|
nn_setEnergyHandler(c, NULL, ne_energy_accumulator);
|
||||||
@@ -472,6 +473,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
//nn_setTmpAddress(c, nn_getComponentAddress(tmpfs));
|
//nn_setTmpAddress(c, nn_getComponentAddress(tmpfs));
|
||||||
|
|
||||||
|
nn_mountComponent(c, wrappedC, 255);
|
||||||
nn_mountComponent(c, screen, -1);
|
nn_mountComponent(c, screen, -1);
|
||||||
nn_mountComponent(c, ocelotCard, -1);
|
nn_mountComponent(c, ocelotCard, -1);
|
||||||
//nn_mountComponent(c, tmpfs, -1);
|
//nn_mountComponent(c, tmpfs, -1);
|
||||||
@@ -495,6 +497,12 @@ int main(int argc, char **argv) {
|
|||||||
size_t scrw, scrh;
|
size_t scrw, scrh;
|
||||||
ncl_getScreenViewport(scrbuf, &scrw, &scrh);
|
ncl_getScreenViewport(scrbuf, &scrw, &scrh);
|
||||||
|
|
||||||
|
ncl_ScreenFlags scrflags = ncl_getScreenFlags(scrbuf);
|
||||||
|
if((scrflags & NCL_SCREEN_ON) == 0) {
|
||||||
|
ncl_unlockScreen(scrbuf);
|
||||||
|
goto skipDrawScreen;
|
||||||
|
}
|
||||||
|
|
||||||
int cheight = GetScreenHeight() / scrh;
|
int cheight = GetScreenHeight() / scrh;
|
||||||
if(cheight != ncl_cellHeight(gc)) {
|
if(cheight != ncl_cellHeight(gc)) {
|
||||||
ncl_destroyGlyphCache(gc);
|
ncl_destroyGlyphCache(gc);
|
||||||
@@ -522,6 +530,7 @@ int main(int argc, char **argv) {
|
|||||||
ncl_unlockScreen(scrbuf);
|
ncl_unlockScreen(scrbuf);
|
||||||
ncl_flushGlyphs(gc);
|
ncl_flushGlyphs(gc);
|
||||||
}
|
}
|
||||||
|
skipDrawScreen:
|
||||||
|
|
||||||
int statY = 10;
|
int statY = 10;
|
||||||
if(sand.buf != NULL) {
|
if(sand.buf != NULL) {
|
||||||
@@ -650,6 +659,7 @@ cleanup:;
|
|||||||
nn_dropComponent(screen);
|
nn_dropComponent(screen);
|
||||||
nn_dropComponent(gpuCard);
|
nn_dropComponent(gpuCard);
|
||||||
nn_dropComponent(keyboard);
|
nn_dropComponent(keyboard);
|
||||||
|
nn_dropComponent(wrappedC);
|
||||||
// rip the universe
|
// rip the universe
|
||||||
nn_destroyUniverse(u);
|
nn_destroyUniverse(u);
|
||||||
ncl_destroyGlyphCache(gc);
|
ncl_destroyGlyphCache(gc);
|
||||||
|
|||||||
@@ -532,6 +532,7 @@ typedef struct ncl_ScreenState {
|
|||||||
ncl_ScreenPixel *pixels;
|
ncl_ScreenPixel *pixels;
|
||||||
ncl_ScreenFlags flags;
|
ncl_ScreenFlags flags;
|
||||||
size_t keyboardCount;
|
size_t keyboardCount;
|
||||||
|
double brightness;
|
||||||
char *keyboards[NCL_MAX_KEYBOARD];
|
char *keyboards[NCL_MAX_KEYBOARD];
|
||||||
} ncl_ScreenState;
|
} ncl_ScreenState;
|
||||||
|
|
||||||
@@ -2269,11 +2270,12 @@ nn_Component *ncl_createScreen(nn_Universe *universe, const char *address, const
|
|||||||
screen->palette = palette;
|
screen->palette = palette;
|
||||||
screen->resolvedPalette = resolvedPalette;
|
screen->resolvedPalette = resolvedPalette;
|
||||||
screen->pixels = pixels;
|
screen->pixels = pixels;
|
||||||
screen->flags = 0;
|
screen->flags = NCL_SCREEN_ON;
|
||||||
screen->depth = config->maxDepth;
|
screen->depth = config->maxDepth;
|
||||||
screen->viewportWidth = screen->width;
|
screen->viewportWidth = screen->width;
|
||||||
screen->viewportHeight = screen->height;
|
screen->viewportHeight = screen->height;
|
||||||
screen->keyboardCount = 0;
|
screen->keyboardCount = 0;
|
||||||
|
screen->brightness = 1;
|
||||||
|
|
||||||
ncl_resetScreen(screen);
|
ncl_resetScreen(screen);
|
||||||
|
|
||||||
@@ -3323,6 +3325,7 @@ const char *ncl_getKeyboard(ncl_ScreenState *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
double ncl_getScreenEnergyUsage(ncl_ScreenState *state) {
|
double ncl_getScreenEnergyUsage(ncl_ScreenState *state) {
|
||||||
|
if((state->flags & NCL_SCREEN_ON) == 0) return 0;
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
for(int y = 1; y <= state->viewportHeight; y++) {
|
for(int y = 1; y <= state->viewportHeight; y++) {
|
||||||
for(int x = 1; x <= state->viewportWidth; x++) {
|
for(int x = 1; x <= state->viewportWidth; x++) {
|
||||||
@@ -3336,6 +3339,14 @@ double ncl_getScreenEnergyUsage(ncl_ScreenState *state) {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double ncl_getScreenBrightness(ncl_ScreenState *state) {
|
||||||
|
return state->brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncl_setScreenBrightness(ncl_ScreenState *state, double brightness) {
|
||||||
|
state->brightness = brightness;
|
||||||
|
}
|
||||||
|
|
||||||
// general stuff
|
// general stuff
|
||||||
|
|
||||||
bool ncl_isNCLID(const char *type) {
|
bool ncl_isNCLID(const char *type) {
|
||||||
|
|||||||
@@ -344,5 +344,7 @@ void ncl_unmountKeyboard(ncl_ScreenState *state, const char *keyboardAddress);
|
|||||||
bool ncl_hasKeyboard(ncl_ScreenState *state, const char *keyboardAddress);
|
bool ncl_hasKeyboard(ncl_ScreenState *state, const char *keyboardAddress);
|
||||||
const char *ncl_getKeyboard(ncl_ScreenState *state, size_t idx);
|
const char *ncl_getKeyboard(ncl_ScreenState *state, size_t idx);
|
||||||
double ncl_getScreenEnergyUsage(ncl_ScreenState *state);
|
double ncl_getScreenEnergyUsage(ncl_ScreenState *state);
|
||||||
|
double ncl_getScreenBrightness(ncl_ScreenState *state);
|
||||||
|
void ncl_setScreenBrightness(ncl_ScreenState *state, double brightness);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
136
src/neonucleus.c
136
src/neonucleus.c
@@ -1219,7 +1219,7 @@ nn_Exit nn_startComputer(nn_Computer *computer) {
|
|||||||
nn_Exit err = computer->arch.handler(&req);
|
nn_Exit err = computer->arch.handler(&req);
|
||||||
if(err) {
|
if(err) {
|
||||||
computer->state = NN_CRASHED;
|
computer->state = NN_CRASHED;
|
||||||
nn_setErrorFromExit(computer, err);
|
if(err != NN_EBADCALL) nn_setErrorFromExit(computer, err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
computer->archState = req.localState;
|
computer->archState = req.localState;
|
||||||
@@ -3619,6 +3619,69 @@ nn_Exit nn_pushModemMessage(nn_Computer *C, const char *modemAddress, const char
|
|||||||
return nn_pushSignal(C, signalVals);
|
return nn_pushSignal(C, signalVals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nn_Computer *nn_fromWrappedComputer(nn_Component *component) {
|
||||||
|
if(nn_strcmp(component->internalID, "NN_WRAPPEDCOMPUTER") == 0) {
|
||||||
|
return component->state;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_Exit nn_transferErrorFrom(nn_Exit exit, nn_Computer *from, nn_Computer *to) {
|
||||||
|
const char *err = nn_getError(from);
|
||||||
|
if(err != NULL) nn_setError(to, err);
|
||||||
|
return exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum nn_CompNum {
|
||||||
|
NN_COMPNUM_START,
|
||||||
|
NN_COMPNUM_STOP,
|
||||||
|
NN_COMPNUM_ISRUNNING,
|
||||||
|
NN_COMPNUM_GETDEVICEINFO,
|
||||||
|
NN_COMPNUM_CRASH,
|
||||||
|
NN_COMPNUM_GETARCH,
|
||||||
|
NN_COMPNUM_ISROBOT,
|
||||||
|
NN_COMPNUM_BEEP,
|
||||||
|
|
||||||
|
NN_COMPNUM_COUNT,
|
||||||
|
} nn_CompNum;
|
||||||
|
|
||||||
|
static nn_Exit nn_computerHandler(nn_ComponentRequest *req) {
|
||||||
|
if(req->action == NN_COMP_DROP) return NN_OK;
|
||||||
|
if(req->action == NN_COMP_SIGNAL) return NN_OK;
|
||||||
|
nn_Computer *target = req->state;
|
||||||
|
nn_Computer *src = req->computer;
|
||||||
|
nn_CompNum method = req->methodIdx;
|
||||||
|
if(src) nn_setError(src, "computer: not implemented yet");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nn_Component *nn_wrapComputer(nn_Computer *computer) {
|
||||||
|
const nn_Method methods[NN_COMPNUM_COUNT] = {
|
||||||
|
[NN_COMPNUM_START] = {"start", "function(): boolean - Attempts to turn on the computer, will return false if it is already on or it failed", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_STOP] = {"stop", "function(): boolean - Attempts to turn ooff the computer, will return false if it is already off or it failed", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_ISRUNNING] = {"isRunning", "function(): boolean - Returns whether it is running or not", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_GETDEVICEINFO] = {"getDeviceInfo", "function(): table<string, table<string, string>> - Returns a table of device information for the computer", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_CRASH] = {"crash", "function(error: string) - Will forcefully crash the computer, if it is running", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_GETARCH] = {"getArchitecture", "function(): string - Get the architecture of the computer", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_ISROBOT] = {"isRobot", "function(): boolean - Returns whether the computer is a robot", NN_INDIRECT},
|
||||||
|
[NN_COMPNUM_BEEP] = {"beep", "function(frequency?: number, duration?: number, volume?: number) - Makes the computer make a beep sound", NN_INDIRECT},
|
||||||
|
};
|
||||||
|
|
||||||
|
nn_Component *c = nn_createComponent(computer->universe, computer->address, "computer");
|
||||||
|
if(c == NULL) return NULL;
|
||||||
|
nn_setComponentState(c, computer);
|
||||||
|
nn_setComponentHandler(c, nn_computerHandler);
|
||||||
|
if(nn_setComponentTypeID(c, "NN_WRAPPEDCOMPUTER")) {
|
||||||
|
nn_dropComponent(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(nn_setComponentMethodsArray(c, methods, NN_COMPNUM_COUNT)) {
|
||||||
|
nn_dropComponent(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
typedef enum nn_EENum {
|
typedef enum nn_EENum {
|
||||||
NN_EENUM_GETSIZE,
|
NN_EENUM_GETSIZE,
|
||||||
NN_EENUM_GETDATASIZE,
|
NN_EENUM_GETDATASIZE,
|
||||||
@@ -5600,6 +5663,9 @@ typedef enum nn_ModemNum {
|
|||||||
NN_MODEMNUM_SEND,
|
NN_MODEMNUM_SEND,
|
||||||
NN_MODEMNUM_BROADCAST,
|
NN_MODEMNUM_BROADCAST,
|
||||||
|
|
||||||
|
NN_MODEMNUM_GETWAKE,
|
||||||
|
NN_MODEMNUM_SETWAKE,
|
||||||
|
|
||||||
NN_MODEMNUM_COUNT,
|
NN_MODEMNUM_COUNT,
|
||||||
} nn_ModemNum;
|
} nn_ModemNum;
|
||||||
|
|
||||||
@@ -5610,6 +5676,7 @@ typedef struct nn_ModemState {
|
|||||||
} nn_ModemState;
|
} nn_ModemState;
|
||||||
|
|
||||||
static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
||||||
|
if(req->action == NN_COMP_SIGNAL) return NN_OK;
|
||||||
nn_Context *ctx = req->ctx;
|
nn_Context *ctx = req->ctx;
|
||||||
nn_ModemState *state = req->classState;
|
nn_ModemState *state = req->classState;
|
||||||
nn_Computer *C = req->computer;
|
nn_Computer *C = req->computer;
|
||||||
@@ -5632,6 +5699,37 @@ static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
|||||||
mreq.state = req->state;
|
mreq.state = req->state;
|
||||||
mreq.modem = &state->modem;
|
mreq.modem = &state->modem;
|
||||||
mreq.localAddress = req->compAddress;
|
mreq.localAddress = req->compAddress;
|
||||||
|
nn_Exit e;
|
||||||
|
|
||||||
|
if(req->action == NN_COMP_DROP) {
|
||||||
|
mreq.action = NN_MODEM_DROP;
|
||||||
|
state->handler(&mreq);
|
||||||
|
nn_free(ctx, state, sizeof(*state));
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(method == NN_MODEMNUM_ISWIRED) {
|
||||||
|
return nn_pushbool(C, isWired);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_ISWIRELESS) {
|
||||||
|
return nn_pushbool(C, isWireless);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_MAXPACKETSIZE) {
|
||||||
|
return nn_pushinteger(C, state->modem.maxPacketSize);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_MAXVALUES) {
|
||||||
|
return nn_pushinteger(C, state->modem.maxValues);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_GETSTRENGTH) {
|
||||||
|
mreq.action = NN_MODEM_GETSTRENGTH;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushinteger(C, mreq.strength);
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_MAXSTRENGTH) {
|
||||||
|
return nn_pushinteger(C, state->modem.maxRange);
|
||||||
|
}
|
||||||
|
|
||||||
if(C) nn_setError(C, "modem: not implemented yet");
|
if(C) nn_setError(C, "modem: not implemented yet");
|
||||||
return NN_EBADCALL;
|
return NN_EBADCALL;
|
||||||
@@ -5659,6 +5757,9 @@ nn_Component *nn_createModem(nn_Universe *universe, const char *address, const n
|
|||||||
|
|
||||||
[NN_MODEMNUM_SEND] = {"send", "function(targetAddress: string, port: integer, ...): boolean - Send a packet", NN_INDIRECT},
|
[NN_MODEMNUM_SEND] = {"send", "function(targetAddress: string, port: integer, ...): boolean - Send a packet", NN_INDIRECT},
|
||||||
[NN_MODEMNUM_BROADCAST] = {"broadcast", "function(port: integer, ...): boolean - Broadcast a packet", NN_INDIRECT},
|
[NN_MODEMNUM_BROADCAST] = {"broadcast", "function(port: integer, ...): boolean - Broadcast a packet", NN_INDIRECT},
|
||||||
|
|
||||||
|
[NN_MODEMNUM_GETWAKE] = {"getWakeMessage", "function(): string?, boolean - Returns the wake message, if any, and whether it is fuzzy", NN_DIRECT},
|
||||||
|
[NN_MODEMNUM_SETWAKE] = {"setWakeMessage", "function(message: string?, fuzzy: boolean) - Changes the wake-up message of the modem", NN_INDIRECT},
|
||||||
};
|
};
|
||||||
|
|
||||||
nn_Exit e = nn_setComponentMethodsArray(
|
nn_Exit e = nn_setComponentMethodsArray(
|
||||||
@@ -5679,3 +5780,36 @@ nn_Component *nn_createModem(nn_Universe *universe, const char *address, const n
|
|||||||
nn_setComponentHandler(c, nn_modemHandler);
|
nn_setComponentHandler(c, nn_modemHandler);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nn_Modem nn_defaultWiredModem = {
|
||||||
|
.maxRange = 0,
|
||||||
|
.maxValues = 8,
|
||||||
|
.maxPacketSize = 8192,
|
||||||
|
.maxOpenPorts = 16,
|
||||||
|
.isWired = true,
|
||||||
|
.basePacketCost = 50,
|
||||||
|
.fullPacketCost = 100,
|
||||||
|
.costPerStrength = 0,
|
||||||
|
};
|
||||||
|
nn_Modem nn_defaultWirelessModems[2] = {
|
||||||
|
NN_INIT(nn_Modem) {
|
||||||
|
.maxRange = 16,
|
||||||
|
.maxValues = 8,
|
||||||
|
.maxPacketSize = 8192,
|
||||||
|
.maxOpenPorts = 16,
|
||||||
|
.isWired = true,
|
||||||
|
.basePacketCost = 100,
|
||||||
|
.fullPacketCost = 500,
|
||||||
|
.costPerStrength = 30,
|
||||||
|
},
|
||||||
|
NN_INIT(nn_Modem) {
|
||||||
|
.maxRange = 400,
|
||||||
|
.maxValues = 8,
|
||||||
|
.maxPacketSize = 8192,
|
||||||
|
.maxOpenPorts = 16,
|
||||||
|
.isWired = true,
|
||||||
|
.basePacketCost = 200,
|
||||||
|
.fullPacketCost = 1000,
|
||||||
|
.costPerStrength = 20,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -903,6 +903,14 @@ nn_Exit nn_popSignal(nn_Computer *computer, size_t *valueCount);
|
|||||||
// The high-level API of the built-in component classes.
|
// The high-level API of the built-in component classes.
|
||||||
// These components still make no assumptions about the OS, and still require handlers to connect them to the outside work.
|
// These components still make no assumptions about the OS, and still require handlers to connect them to the outside work.
|
||||||
|
|
||||||
|
// Wrapping a computer as a component.
|
||||||
|
// It's a new instance each time.
|
||||||
|
// The computer MUST NOT be dropped before this component is fully gone.
|
||||||
|
|
||||||
|
nn_Exit nn_transferErrorFrom(nn_Exit exit, nn_Computer *from, nn_Computer *to);
|
||||||
|
nn_Computer *nn_fromWrappedComputer(nn_Component *component);
|
||||||
|
nn_Component *nn_wrapComputer(nn_Computer *computer);
|
||||||
|
|
||||||
// EEPROM class
|
// EEPROM class
|
||||||
|
|
||||||
// reads and writes are always 1/1
|
// reads and writes are always 1/1
|
||||||
@@ -1586,10 +1594,6 @@ extern nn_Modem nn_defaultWirelessModems[2];
|
|||||||
typedef enum nn_ModemAction {
|
typedef enum nn_ModemAction {
|
||||||
// modem dropped
|
// modem dropped
|
||||||
NN_MODEM_DROP,
|
NN_MODEM_DROP,
|
||||||
// modem mounted to a computer, meant to bind
|
|
||||||
NN_MODEM_MOUNTED,
|
|
||||||
// modem unmounted to a computer, meant to unbind
|
|
||||||
NN_MODEM_UNMOUNTED,
|
|
||||||
// check whether a port is open
|
// check whether a port is open
|
||||||
NN_MODEM_ISOPEN,
|
NN_MODEM_ISOPEN,
|
||||||
// open a port
|
// open a port
|
||||||
@@ -1602,6 +1606,8 @@ typedef enum nn_ModemAction {
|
|||||||
NN_MODEM_SEND,
|
NN_MODEM_SEND,
|
||||||
// get current modem strength
|
// get current modem strength
|
||||||
NN_MODEM_GETSTRENGTH,
|
NN_MODEM_GETSTRENGTH,
|
||||||
|
// set current modem strength
|
||||||
|
NN_MODEM_SETSTRENGTH,
|
||||||
// returns the wake message
|
// returns the wake message
|
||||||
NN_MODEM_GETWAKEMESSAGE,
|
NN_MODEM_GETWAKEMESSAGE,
|
||||||
// set the wake message
|
// set the wake message
|
||||||
|
|||||||
Reference in New Issue
Block a user