Compare commits

...

2 commits

Author SHA1 Message Date
Scott Duensing
f28bbd476e Library loading / unloading working. 2025-12-21 19:39:05 -06:00
Scott Duensing
646ef619b0 Makefile now builds DYNs magically. 2025-12-20 19:35:54 -06:00
14 changed files with 391 additions and 180 deletions

View file

@ -22,6 +22,9 @@
# #
# This Makefile is terrible. I have no idea what I'm doing.
# Tools # Tools
CC := gcc CC := gcc
AR := ar AR := ar
@ -29,7 +32,7 @@ DXE3GEN := dxe3gen
EXE2COFF := exe2coff EXE2COFF := exe2coff
# Compiler Settings # Compiler Settings
CFLAGS := -DPLATFORM_DOS -Wall CFLAGS := -DPLATFORM_DOS -Wall -MD
LDFLAGS := LDFLAGS :=
# Output Directories # Output Directories
@ -42,7 +45,7 @@ FNT := $(BIN)/fonts
FIN := font/in FIN := font/in
# Include Paths # Include Paths
INC := ../include include 3rdparty 3rdparty/pthreads/include INC := include 3rdparty 3rdparty/pthreads/include roo_e
# Font Compiler Source and Target - NOTE: This is a Linux binary! # Font Compiler Source and Target - NOTE: This is a Linux binary!
FONT_ELF := font FONT_ELF := font
@ -50,17 +53,11 @@ FONT_SRC := $(shell find font/src -name '*.c')
FONT_OBJ := $(FONT_SRC:%=$(OBJ)/%.o) FONT_OBJ := $(FONT_SRC:%=$(OBJ)/%.o)
FONT_LIB := -lm FONT_LIB := -lm
# Roo/E Dynamic Libraries
DYNS_EXE := stbimage.dyn
DYNS_SRC := $(shell find dyn/stbimage -name '*.c')
DYNS_OBJ := $(DYNS_SRC:%=$(OBJ)/%.o)
DYNS_LIB :=
# Roo/E Source and Target # Roo/E Source and Target
ROOE_EXE := roo_e.exe ROOE_EXE := roo_e.exe
ROOE_SRC := $(shell find roo_e -name '*.c') ROOE_SRC := $(shell find roo_e -name '*.c')
ROOE_OBJ := $(ROOE_SRC:%=$(OBJ)/%.o) ROOE_OBJ := $(ROOE_SRC:%=$(OBJ)/%.o)
ROOE_LIB := 3rdparty/pthreads/lib/libgthreads.a -lgcc ROOE_LIB := 3rdparty/pthreads/lib/libgthreads.a -lgcc -lm
# MultiPlayer Game Client # MultiPlayer Game Client
MPGC_EXE := kpsmpgc.app MPGC_EXE := kpsmpgc.app
@ -68,13 +65,17 @@ MPGC_SRC := $(shell find kpsmpgc -name '*.c')
MPGC_OBJ := $(MPGC_SRC:%=$(OBJ)/%.o) MPGC_OBJ := $(MPGC_SRC:%=$(OBJ)/%.o)
MPGC_LIB := MPGC_LIB :=
FONTS := $(FNT)/vga4x8.fnt $(FNT)/vga8x8.fnt $(FNT)/vga8x14.fnt $(FNT)/vga8x16.fnt DYNS := kpsvideo stbimage
FONTS := vga4x8 vga8x8 vga8x14 vga8x16
# Wiring # Wiring
FONT_PNGS := $(subst $(FNT),$(FIN),$(FONTS)) INC_FLAGS := $(addprefix -I,$(INC))
FONT_PNGS := $(subst .fnt,.png,$(FONTS_PNGS)) CFLAGS += $(INC_FLAGS)
INC_FLAGS := $(addprefix -I,$(INC)) APP_OBJS := $(ROOE_OBJ) $(MPGC_OBJ)
CFLAGS += $(INC_FLAGS) FONTS := $(addprefix $(FNT)/,$(addsuffix .fnt,$(FONTS)))
FONT_PNGS := $(subst .fnt,.png,$(subst $(FNT),$(FIN),$(FONTS)))
DYN_FILES := $(foreach DIR,$(DYNS),$(DYN)/$(DIR).dyn)
DYN_SOURCE := $(foreach DIR,$(DYNS),$(shell find dyn/$(DIR) -name '*.c' -or -name '*.h'))
# Force User to Run This Using Toolchains # Force User to Run This Using Toolchains
.PHONY: use_build_script .PHONY: use_build_script
@ -83,7 +84,7 @@ use_build_script:
# Build Everything # Build Everything
.PHONY: dos .PHONY: dos
dos: $(BIN)/$(ROOE_EXE) $(APP)/$(MPGC_EXE) $(DYN)/$(DYNS_EXE) dos: $(BIN)/$(ROOE_EXE) $(APP)/$(MPGC_EXE) $(DYN_FILES) sdk_extra
.PHONY: linux .PHONY: linux
linux: $(FONTS) linux: $(FONTS)
@ -98,7 +99,7 @@ $(BIN)/$(FONT_ELF): $(FONT_OBJ) Makefile
mkdir -p $(dir $@) $(BIN)/fonts mkdir -p $(dir $@) $(BIN)/fonts
$(CC) $(FONT_OBJ) -o $@ $(LDFLAGS) $(FONT_LIB) $(CC) $(FONT_OBJ) -o $@ $(LDFLAGS) $(FONT_LIB)
$(FONTS) &: $(FIN)/vga4x8.png $(FIN)/vga4x8.png $(FIN)/vga4x8.png $(FIN)/vga4x8.png $(BIN)/$(FONT_ELF) $(FONTS) &: $(FONT_PNGS) $(BIN)/$(FONT_ELF)
cd $(BIN) && ./$(FONT_ELF) cd $(BIN) && ./$(FONT_ELF)
# Roo/E Target # Roo/E Target
@ -115,15 +116,27 @@ $(APP)/$(MPGC_EXE): $(MPGC_OBJ) Makefile
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(DXE3GEN) -o $@ $(MPGC_OBJ) -U $(LDFLAGS) $(MPGC_LIB) $(DXE3GEN) -o $@ $(MPGC_OBJ) -U $(LDFLAGS) $(MPGC_LIB)
# DYNS Target # DYN Targets - This is NOT how make should be used.
$(DYN)/$(DYNS_EXE): $(DYNS_OBJ) Makefile .PHONY: dyns
mkdir -p $(dir $@) $(DYN_FILES): $(DYN_SOURCE) Makefile
$(AR) rcs $(OBJ)/$(DYNS_EXE).a $(DYNS_OBJ) echo $(DYN_SOURCE)
$(DXE3GEN) -o $@ -Y $@.a --whole-archive -U $(OBJ)/$(DYNS_EXE).a $(LDFLAGS) $(DYNS_LIB) mkdir -p $(DYN) $(OBJ)/dyn/$(basename $(notdir $@)) $(SDK)/lib $(SDK)/include
mkdir -p $(SDK) $(foreach CFILE,$(shell find dyn/$(basename $(notdir $@)) -name '*.c'),$(CC) $(CFLAGS) -o $(OBJ)/dyn/$(basename $(notdir $@))/$(subst dyn/$(basename $(notdir $@))/,,$(CFILE).o) -c $(CFILE) && ) true
mv $(DYN)/$(DYNS_EXE).a $(SDK)/. $(AR) rcs $(OBJ)/dyn/$(basename $(notdir $@)).a $(OBJ)/dyn/$(basename $(notdir $@))/*.o
$(DXE3GEN) -o $@ -Y $@.a --whole-archive -U $(OBJ)/dyn/$(basename $(notdir $@)).a $(LDFLAGS)
mv $@.a $(SDK)/lib/.
if [ ! -z "$(shell find dyn/$(basename $(notdir $@)) -name '*.h')" ]; then cp $(shell find dyn/$(basename $(notdir $@)) -name '*.h') $(SDK)/include/.; fi
# Extra SDK Files
.PHONEY: sdk_extra
sdk_extra: 3rdparty/stbds.h 3rdparty/stbimage.h Makefile
cp 3rdparty/stbds.h 3rdparty/stbimage.h ${SDK}/include/.
cp roo_e/*.h ${SDK}/include/.
# Build C Files # Build C Files
$(OBJ)/%.c.o: %.c $(OBJ)/%.c.o: %.c
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
# Track Header Changes in APPs and Roo/E
-include $(APP_OBJS:.o=.d)

37
dyn/kpsvideo/kpsvideo.c Normal file
View file

@ -0,0 +1,37 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing
*
* http://kangaroopunch.com
*
*
* This file is part of Roo/E.
*
* Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/
#include "roo_e.h"
#include "kpsvideo.h"
int dynStart(void) {
printf("kpsvideo starting!\n");
return 0;
}
int dynStop(void) {
printf("kpsvideo stopping!\n");
return 0;
}

27
dyn/kpsvideo/kpsvideo.h Normal file
View file

@ -0,0 +1,27 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing
*
* http://kangaroopunch.com
*
*
* This file is part of Roo/E.
*
* Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef KPSVIDEO_H
#define KPSVIDEO_H
#endif // KPSVIDEO_H

View file

@ -1,30 +1,30 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit /* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing * Copyright (C) 2026 Scott Duensing
* *
* http://kangaroopunch.com * http://kangaroopunch.com
* *
* *
* This file is part of Roo/E. * This file is part of Roo/E.
* *
* Roo/E is free software: you can redistribute it and/or modify it under the * Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free * terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) * Software Foundation, either version 3 of the License, or (at your option)
* any later version. * any later version.
* *
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>. * along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include "roo_e.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stbimage.h"
int dynStart(void) { int dynStart(void) {

2
env.sh
View file

@ -25,4 +25,4 @@
eval "$(../toolchains/toolchains.sh use x86 dos)" eval "$(../toolchains/toolchains.sh use x86 dos)"
export C_INCLUDE_PATH=${HOME}/code/toolchains/x-tools/djgpp/i586-pc-msdosdjgpp/sys-include export C_INCLUDE_PATH=${HOME}/code/toolchains/x-tools/djgpp/i586-pc-msdosdjgpp/sys-include:roo_e

View file

@ -1,24 +1,24 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit /* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing * Copyright (C) 2026 Scott Duensing
* *
* http://kangaroopunch.com * http://kangaroopunch.com
* *
* *
* This file is part of Roo/E. * This file is part of Roo/E.
* *
* Roo/E is free software: you can redistribute it and/or modify it under the * Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free * terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) * Software Foundation, either version 3 of the License, or (at your option)
* any later version. * any later version.
* *
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>. * along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include <stdio.h>
@ -30,7 +30,7 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG #define STBI_ONLY_PNG
#include "stb_image.h" #include "stbimage.h"
#include "stddclmr.h" #include "stddclmr.h"

View file

@ -1,36 +1,36 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit /* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing * Copyright (C) 2026 Scott Duensing
* *
* http://kangaroopunch.com * http://kangaroopunch.com
* *
* *
* This file is part of Roo/E. * This file is part of Roo/E.
* *
* Roo/E is free software: you can redistribute it and/or modify it under the * Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free * terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) * Software Foundation, either version 3 of the License, or (at your option)
* any later version. * any later version.
* *
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>. * along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <stdio.h> #include "roo_e.h"
#include "stb_image.h" #include "stbimage.h"
void __attribute__((constructor)) registerApp(void) { ROO_CONSTRUCTOR registerApp(void) {
printf("App Loaded!\n"); printf("App Loaded!\n");
} }
void __attribute__((destructor)) unregisterApp(void) { ROO_DESTRUCTOR unregisterApp(void) {
printf("App Unloaded!\n"); printf("App Unloaded!\n");
} }
@ -43,3 +43,9 @@ int appMain(const int argc, char* argv[]) {
printf("stbi_failure_reason: [%s]\n", stbi_failure_reason()); printf("stbi_failure_reason: [%s]\n", stbi_failure_reason());
return 0; return 0;
} }
int appStop(RooStopReasonT why) {
printf("App Stopped!\n");
return ROO_ABORT_NONE;
}

View file

@ -22,22 +22,11 @@
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <dirent.h>
#include <math.h>
#include "pthread.h"
// ReSharper disable once CppUnusedIncludeDirective
#include "stddclmr.h"
#include "util.h"
#define STB_DS_IMPLEMENTATION #define STB_DS_IMPLEMENTATION
#include "stb_ds.h" #include "roo_e.h"
int startApp(const char *appName, int argc, char *argv[]); static RooNamedPointerT **_appList = NULL; // NOLINT
#ifdef PLATFORM_DOS #ifdef PLATFORM_DOS
@ -118,55 +107,83 @@ void *dxeResolver(const char *symbol) {
void *to; void *to;
} funcPtrCast; } funcPtrCast;
printf("%s: undefined symbol in dynamic module!\n", symbol); printf("ROO/E: %s: undefined symbol in dynamic module!\n", symbol);
funcPtrCast.from = lastResort; funcPtrCast.from = lastResort;
return funcPtrCast.to; // NOLINT return funcPtrCast.to; // NOLINT
} }
static int lastResort(void) { static int lastResort(void) {
printf("Last resort function called!\n"); printf("ROO/E: Last resort function called!\n");
return 0; return 0;
} }
#endif // PLATFORM_DOS #endif // PLATFORM_DOS
int startApp(const char *appName, const int argc, char *argv[]) { int rooStartApp(const char *appName, const int argc, char *argv[], RooNamedPointerT **handle) {
void *dxe = NULL; RooNamedPointerT *namedPointer = NULL;
int result = -1; int result = -1;
char *filename = NULL; int (*appMain)(const int argc, char *argv[]); // NOLINT
int (*appMain)(const int argc, char *argv[]);
union { union {
void *from; void *from;
int (*to)(const int argc, char *argv[]); int (*to)(const int argc, char *argv[]);
} appPtrCast; } appPtrCast; // NOLINT
dlerror(); // Clear any existing error. dlerror(); // Clear any existing error.
filename = utilCreateString("app/%s.app", appName); NEW(RooNamedPointerT, namedPointer);
dxe = dlopen(filename, RTLD_LAZY); namedPointer->name = utilCreateString("app/%s.app", appName);
if (!dxe) { namedPointer->pointer = dlopen(namedPointer->name, RTLD_LAZY);
printf("Unable to load %s! %s\n", filename, dlerror()); if (!namedPointer->pointer) {
printf("ROO/E: Unable to load %s! %s\n", namedPointer->name, dlerror());
} else { } else {
appPtrCast.from = dlsym(dxe, "_appMain"); appPtrCast.from = dlsym(namedPointer->pointer, "_appMain");
appMain = appPtrCast.to; // NOLINT appMain = appPtrCast.to; // NOLINT
result = appMain(argc, argv); result = appMain(argc, argv);
arrput(_appList, namedPointer);
if (handle != NULL) *handle = namedPointer->pointer;
} }
dlclose(dxe);
return result; return result;
} }
RooAbortReasonT rooStopApp(RooNamedPointerT **appHandle, RooStopReasonT reason) {
RooAbortReasonT abort = ROO_ABORT_NONE;
RooNamedPointerT *namedPointer = NULL;
int (*appStop)(RooStopReasonT reason);
union {
void *from;
int (*to)(RooStopReasonT reason);
} appPtrCast; // NOLINT
namedPointer = *appHandle;
appPtrCast.from = dlsym(namedPointer->pointer, "_appStop");
if (appPtrCast.from != NULL) {
appStop = appPtrCast.to; // NOLINT
abort = appStop(reason);
}
if (abort == ROO_ABORT_NONE) {
dlclose(namedPointer->pointer);
DEL(namedPointer->name);
DEL(namedPointer);
}
return abort;
}
int main(const int argc, char *argv[]) { int main(const int argc, char *argv[]) {
void *dxe = NULL; DIR *dir = NULL;
DIR *dir = NULL; struct dirent *dirent = NULL;
struct dirent *dirent = NULL; int result;
char *filename = NULL; RooAbortReasonT abort;
int (*dynInit)(void); RooNamedPointerT **dynList = NULL;
int result; RooNamedPointerT *namedPointer = NULL;
int (*dynInitStop)(void);
union { union {
void *from; void *from;
@ -184,40 +201,80 @@ int main(const int argc, char *argv[]) {
#endif // PLATFORM_DOS #endif // PLATFORM_DOS
// Load libraries. // Load libraries.
debug("Loading dynamic libraries.\n"); debug("ROO/E: Loading dynamic libraries.\n");
if ((dir = opendir("dyn/")) == NULL) { if ((dir = opendir("dyn/")) == NULL) {
printf("Unable to open dyn directory!\n"); printf("ROO/E: Unable to open dyn directory!\n");
exit(1); exit(1);
} }
while ((dirent = readdir(dir))) { while ((dirent = readdir(dir))) {
if ((dirent->d_type == DT_REG) || (dirent->d_type == DT_LNK)) { if ((dirent->d_type == DT_REG) || (dirent->d_type == DT_LNK)) {
if (utilEndsWith(dirent->d_name, ".dyn", false)) { if (utilEndsWith(dirent->d_name, ".dyn", false)) {
filename = utilCreateString("dyn/%s", dirent->d_name); NEW(RooNamedPointerT, namedPointer);
namedPointer->name = utilCreateString("dyn/%s", dirent->d_name);
dlerror(); // Clear any existing error. dlerror(); // Clear any existing error.
dxe = dlopen(filename,RTLD_LAZY | RTLD_GLOBAL); namedPointer->pointer = dlopen(namedPointer->name,RTLD_LAZY | RTLD_GLOBAL);
if (!dxe) { if (!namedPointer->pointer) {
printf("Unable to load %s! %s\n", filename, dlerror()); printf("ROO/E: Unable to load %s! %s\n", namedPointer->name, dlerror());
exit(1); exit(1);
} }
debug("Loaded %s.\n", filename); debug("ROO/E: Loaded %s.\n", namedPointer->name);
dynPtrCast.from = dlsym(dxe, "_dynStart"); dynPtrCast.from = dlsym(namedPointer->pointer, "_dynStart");
if (dynPtrCast.from != NULL) { if (dynPtrCast.from != NULL) {
dynInit = dynPtrCast.to; // NOLINT dynInitStop = dynPtrCast.to; // NOLINT
debug("Starting %s.\n", filename); debug("ROO/E: Starting %s.\n", namedPointer->name);
result = dynInit(); result = dynInitStop();
if (result != 0) { if (result != 0) {
printf("%s failed to start!\n", filename); printf("ROO/E: %s failed to start!\n", namedPointer->name);
exit(1); exit(1);
} }
} }
free(filename); arrput(dynList, namedPointer);
} }
} }
} }
closedir(dir); closedir(dir);
// Load the Shell. debug("ROO/E: Loaded %d libraries.\n", arrlen(dynList));
result = startApp("kpsmpgc", 0, NULL);
// Load the Shell. This needs to be configurable.
result = rooStartApp("kpsmpgc", 0, NULL, NULL);
// Run as long as apps are running.
while (arrlen(_appList) > 0) {
// Wait for all apps to exit.
// Unload APPs.
while (arrlen(_appList) > 0) {
namedPointer = _appList[0]; // NOLINT
debug("ROO/E: Stopping %s\n", namedPointer->name);
abort = rooStopApp(&namedPointer, ROO_STOP_SHUTDOWN);
if (abort == ROO_ABORT_NONE) {
arrdel(_appList, 0);
} else {
break; // Somebody didn't want to stop.
}
}
}
// Unload DYNs
debug("ROO/E: Unloading %d libraries.\n", arrlen(dynList));
while (arrlen(dynList) > 0) {
namedPointer = dynList[0]; // NOLINT
debug("ROO/E: Stopping %s\n", namedPointer->name);
dynPtrCast.from = dlsym(namedPointer->pointer, "_dynStop");
if (dynPtrCast.from != NULL) {
dynInitStop = dynPtrCast.to; // NOLINT
result = dynInitStop();
if (result != 0) {
printf("ROO/E: %s failed to stop!\n", namedPointer->name);
exit(1);
}
}
arrdel(dynList, 0);
dlclose(namedPointer->pointer);
DEL(namedPointer->name);
DEL(namedPointer);
}
return result; return result;
} }

71
roo_e/roo_e.h Normal file
View file

@ -0,0 +1,71 @@
/*
* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing
*
* http://kangaroopunch.com
*
*
* This file is part of Roo/E.
*
* Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ROO_E_H
#define ROO_E_H
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <dirent.h>
#include <math.h>
#include "pthread.h"
#include "stbds.h"
#include "util.h"
#include "stddclmr.h"
#define ROO_CONSTRUCTOR void __attribute__((constructor))
#define ROO_DESTRUCTOR void __attribute__((destructor))
// Allocation helpers. ***TODO*** Check for failure.
#define NEW(t,v) (v)=(t*)malloc(sizeof(t))
#define DEL(v) {if(v) {free(v); v=NULL;}}
typedef struct RooNamedPointerS {
char *name;
void *pointer;
} RooNamedPointerT;
typedef enum {
ROO_STOP_EXITING = 0, // App quit
ROO_STOP_SHUTDOWN, // Roo/E shutdown
ROO_STOP_COUNT
} RooStopReasonT;
typedef enum {
ROO_ABORT_NONE = 0, // Don't abort stopping the app
ROO_ABORT_CANCEL, // Try to keep the app alive
ROO_ABORT_COUNT
} RooAbortReasonT;
int rooStartApp(const char *appName, int argc, char *argv[], RooNamedPointerT **handle);
RooAbortReasonT rooStopApp(RooNamedPointerT **appHandle, RooStopReasonT reason);
#endif // ROO_E_H

View file

@ -1,24 +1,24 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit /* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing * Copyright (C) 2026 Scott Duensing
* *
* http://kangaroopunch.com * http://kangaroopunch.com
* *
* *
* This file is part of Roo/E. * This file is part of Roo/E.
* *
* Roo/E is free software: you can redistribute it and/or modify it under the * Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free * terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) * Software Foundation, either version 3 of the License, or (at your option)
* any later version. * any later version.
* *
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>. * along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>

View file

@ -1,24 +1,24 @@
/* Roo/E, the Kangaroo Punch Portable GUI Toolkit /* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2026 Scott Duensing * Copyright (C) 2026 Scott Duensing
* *
* http://kangaroopunch.com * http://kangaroopunch.com
* *
* *
* This file is part of Roo/E. * This file is part of Roo/E.
* *
* Roo/E is free software: you can redistribute it and/or modify it under the * Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free * terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) * Software Foundation, either version 3 of the License, or (at your option)
* any later version. * any later version.
* *
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY * Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. * details.
* *
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>. * along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*/ */
#ifndef UTIL_H #ifndef UTIL_H