Compare commits
2 commits
e2c517b529
...
f28bbd476e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f28bbd476e | ||
|
|
646ef619b0 |
14 changed files with 391 additions and 180 deletions
0
3rdparty/stb_ds.h → 3rdparty/stbds.h
vendored
0
3rdparty/stb_ds.h → 3rdparty/stbds.h
vendored
0
3rdparty/stb_image.h → 3rdparty/stbimage.h
vendored
0
3rdparty/stb_image.h → 3rdparty/stbimage.h
vendored
55
Makefile
55
Makefile
|
|
@ -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))
|
|
||||||
FONT_PNGS := $(subst .fnt,.png,$(FONTS_PNGS))
|
|
||||||
INC_FLAGS := $(addprefix -I,$(INC))
|
INC_FLAGS := $(addprefix -I,$(INC))
|
||||||
CFLAGS += $(INC_FLAGS)
|
CFLAGS += $(INC_FLAGS)
|
||||||
|
APP_OBJS := $(ROOE_OBJ) $(MPGC_OBJ)
|
||||||
|
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
37
dyn/kpsvideo/kpsvideo.c
Normal 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
27
dyn/kpsvideo/kpsvideo.h
Normal 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
|
||||||
|
|
@ -21,10 +21,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#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
2
env.sh
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#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;
|
||||||
|
}
|
||||||
|
|
|
||||||
147
roo_e/main.c
147
roo_e/main.c
|
|
@ -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;
|
||||||
char *filename = NULL;
|
|
||||||
int (*dynInit)(void);
|
|
||||||
int result;
|
int result;
|
||||||
|
RooAbortReasonT abort;
|
||||||
|
RooNamedPointerT **dynList = NULL;
|
||||||
|
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
71
roo_e/roo_e.h
Normal 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
|
||||||
Loading…
Add table
Reference in a new issue