From ea1947ffcc606d757357398b24e74a3f4ecefa07 Mon Sep 17 00:00:00 2001 From: neonloop Date: Wed, 20 Oct 2021 14:54:27 +0000 Subject: Initial commit from steward-fu release --- modules/mod_proc/mod_proc.c | 514 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 514 insertions(+) create mode 100644 modules/mod_proc/mod_proc.c (limited to 'modules/mod_proc/mod_proc.c') diff --git a/modules/mod_proc/mod_proc.c b/modules/mod_proc/mod_proc.c new file mode 100644 index 0000000..9d8c31d --- /dev/null +++ b/modules/mod_proc/mod_proc.c @@ -0,0 +1,514 @@ +/* + * Copyright © 2006-2016 SplinterGU (Fenix/Bennugd) + * Copyright © 2002-2006 Fenix Team (Fenix) + * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include +#include + +#include "bgdrtm.h" + +#include "bgddl.h" +#include "dlvaracc.h" +#include "instance.h" + +#include "xstrings.h" + +#include "mod_proc.h" + +/* ----------------------------------------------------------------- */ + +enum +{ + PROCESS_ID = 0, + PROCESS_TYPE, + STATUS, + ID_SCAN, + TYPE_SCAN, + CONTEXT, + SIGNAL_ACTION +} ; + +/* ----------------------------------------------------------------- */ +/* Son las variables que se desea acceder. */ +/* El interprete completa esta estructura, si la variable existe. */ +/* (usada en tiempo de ejecucion) */ +DLVARFIXUP __bgdexport( mod_proc, locals_fixup )[] = +{ + /* Nombre de variable local, offset al dato, tamaño del elemento, cantidad de elementos */ + { "id", NULL, -1, -1 }, + { "reserved.process_type", NULL, -1, -1 }, + { "reserved.status", NULL, -1, -1 }, + { "mod_proc_reserved.id_scan", NULL, -1, -1 }, + { "mod_proc_reserved.type_scan", NULL, -1, -1 }, + { "mod_proc_reserved.context", NULL, -1, -1 }, + { "mod_proc_reserved.signal_action", NULL, -1, -1 }, + { NULL, NULL, -1, -1 } +}; + +/* ----------------------------------------------------------------- */ + +void __bgdexport( mod_proc, process_exec_hook )( INSTANCE * r ) +{ + LOCDWORD( mod_proc, r, TYPE_SCAN ) = 0; + LOCDWORD( mod_proc, r, ID_SCAN ) = 0; + LOCDWORD( mod_proc, r, CONTEXT ) = 0; +} + +/* ----------------------------------------------------------------- */ +/* Interacción entre procesos */ + +static void _modproc_kill_all() +{ + INSTANCE * i = first_instance ; + while ( i ) + { + LOCDWORD( mod_proc, i, STATUS ) = STATUS_KILLED ; + i = i->next ; + } +} + +/* --------------------------------------------------------------------------- */ +/** EXIT () + * Leaves the program at next frame + */ + +/* ----------------------------------------------------------------- */ + +static int modproc_exit_0( INSTANCE * my, int * params ) +{ + exit_value = 0; + must_exit = 1 ; + + return 1 ; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_exit_1( INSTANCE * my, int * params ) +{ + printf( string_get( params[0] ) ); + printf( "\n" ); + fflush( stdout ); + string_discard( params[0] ); + + exit_value = 0; + must_exit = 1 ; + + return 1 ; +} + +/* --------------------------------------------------------------------------- */ + +static int modproc_exit( INSTANCE * my, int * params ) +{ + _modproc_kill_all(); + + printf( string_get( params[0] ) ); + printf( "\n" ); + fflush( stdout ); + string_discard( params[0] ); + + exit_value = params[1]; + must_exit = 1 ; + + return 1 ; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_running( INSTANCE * my, int * params ) +{ + INSTANCE * i, * ctx; + + if ( params[0] == 0 ) return 0; + + if ( params[0] >= FIRST_INSTANCE_ID ) + { + i = instance_get( params[0] ) ; + if ( i && ( LOCDWORD( mod_proc, i, STATUS ) & ~STATUS_WAITING_MASK ) >= STATUS_RUNNING ) return 1; + return 0; + } + + ctx = NULL; + while ( ( i = instance_get_by_type( params[0], &ctx ) ) ) + { + if ( ( LOCDWORD( mod_proc, i, STATUS ) & ~STATUS_WAITING_MASK ) >= STATUS_RUNNING ) return 1; + } + + return 0; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_signal( INSTANCE * my, int * params ) +{ + INSTANCE * i, * ctx; + int fake_params[2] ; + + if ( params[0] == ALL_PROCESS ) + { + /* Signal all process but my */ + int myid = LOCDWORD( mod_proc, my, PROCESS_ID ); + fake_params[1] = ( params[1] >= S_TREE ) ? params[1] - S_TREE : params[1] ; + i = first_instance ; + while ( i ) + { + if ( LOCDWORD( mod_proc, i, PROCESS_ID ) != myid && ( LOCDWORD( mod_proc, i, STATUS ) & ~STATUS_WAITING_MASK ) > STATUS_KILLED ) + { + fake_params[0] = LOCDWORD( mod_proc, i, PROCESS_ID ) ; + modproc_signal( my, fake_params ) ; + } + i = i->next ; + } + return 0 ; + } + else if ( params[0] < FIRST_INSTANCE_ID ) + { + /* Signal by type */ + fake_params[1] = params[1] ; + + ctx = NULL; + while ( ( i = instance_get_by_type( params[0], &ctx ) ) ) + { + fake_params[0] = LOCDWORD( mod_proc, i, PROCESS_ID ) ; + modproc_signal( my, fake_params ) ; + } + return 0 ; + } + + i = instance_get( params[0] ) ; + if ( i ) + { + if (( LOCDWORD( mod_proc, i, STATUS ) & ~STATUS_WAITING_MASK ) > STATUS_KILLED ) + { + switch ( params[1] ) + { + case S_KILL: + case S_KILL_FORCE: + if ( params[1] == S_KILL_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_KILL ) ) + LOCDWORD( mod_proc, i, STATUS ) = STATUS_KILLED ; + break ; + + case S_WAKEUP: + case S_WAKEUP_FORCE: + if ( params[1] == S_WAKEUP_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_WAKEUP ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_RUNNING ; + break ; + + case S_SLEEP: + case S_SLEEP_FORCE: + if ( params[1] == S_SLEEP_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_SLEEP ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_SLEEPING ; + break ; + + case S_FREEZE: + case S_FREEZE_FORCE: + if ( params[1] == S_FREEZE_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_FREEZE ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_FROZEN ; + break ; + + case S_KILL_TREE: + case S_KILL_TREE_FORCE: + if ( params[1] == S_KILL_TREE_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_KILL_TREE ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_KILLED ; + break ; + + case S_WAKEUP_TREE: + case S_WAKEUP_TREE_FORCE: + if ( params[1] == S_WAKEUP_TREE_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_WAKEUP_TREE ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_RUNNING ; + break ; + + case S_SLEEP_TREE: + case S_SLEEP_TREE_FORCE: + if ( params[1] == S_SLEEP_TREE_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_SLEEP_TREE ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_SLEEPING ; + break ; + + case S_FREEZE_TREE: + case S_FREEZE_TREE_FORCE: + if ( params[1] == S_FREEZE_TREE_FORCE || !( LOCDWORD( mod_proc, i, SIGNAL_ACTION ) & SMASK_FREEZE_TREE ) ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_FROZEN ; + break ; + + default: + return 1 ; + } + } + + if ( params[1] >= S_TREE ) + { + fake_params[1] = params[1] ; + i = instance_getson( i ) ; + while ( i ) + { + fake_params[0] = LOCDWORD( mod_proc, i, PROCESS_ID ) ; + modproc_signal( my, fake_params ) ; + i = instance_getbigbro( i ) ; + } + } + } + return 1 ; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_signal_action( INSTANCE * my, int * params ) +{ + int action = params[1]; + + if ( my ) + { + switch ( params[0] ) + { + case S_KILL: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_KILL; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_KILL; + break; + } + break ; + + case S_WAKEUP: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_WAKEUP; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_WAKEUP; + break; + } + break ; + + case S_SLEEP: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_SLEEP; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_SLEEP; + break; + } + break ; + + case S_FREEZE: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_FREEZE; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_FREEZE; + break; + } + break ; + + case S_KILL_TREE: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_KILL_TREE; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_KILL_TREE; + break; + } + break ; + + case S_WAKEUP_TREE: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_WAKEUP_TREE; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_WAKEUP_TREE; + break; + } + break ; + + case S_SLEEP_TREE: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_SLEEP_TREE; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_SLEEP_TREE; + break; + } + break ; + + case S_FREEZE_TREE: + switch ( action ) + { + case S_IGN: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) |= SMASK_FREEZE_TREE; + break; + + case S_DFL: + LOCDWORD( mod_proc, my, SIGNAL_ACTION ) &= ~SMASK_FREEZE_TREE; + break; + } + break ; + } + } + return 1 ; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_signal_action3( INSTANCE * my, int * params ) +{ + INSTANCE * i, * ctx ; + + if ( params[0] == ALL_PROCESS ) + { + i = first_instance ; + while ( i ) + { + modproc_signal_action( i, ¶ms[1] ) ; + i = i->next ; + } + return 0 ; + } + else if ( params[0] < FIRST_INSTANCE_ID ) + { + ctx = NULL; + while ( ( i = instance_get_by_type( params[0], &ctx ) ) ) + { + modproc_signal_action( i, ¶ms[1] ) ; + } + return 0 ; + } + + i = instance_get( params[0] ) ; + if ( i ) modproc_signal_action( i, ¶ms[1] ) ; + + return 1; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_let_me_alone( INSTANCE * my, int * params ) +{ + INSTANCE * i = first_instance ; + + while ( i ) + { + if ( i != my && ( LOCDWORD( mod_proc, i, STATUS ) & ~STATUS_WAITING_MASK ) != STATUS_DEAD ) + LOCDWORD( mod_proc, i, STATUS ) = ( LOCDWORD( mod_proc, i, STATUS ) & STATUS_WAITING_MASK ) | STATUS_KILLED ; + i = i->next ; + } + if ( LOCDWORD( mod_proc, my, STATUS ) > STATUS_KILLED ) LOCDWORD( mod_proc, my, STATUS ) = STATUS_RUNNING; + return 1 ; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_get_id( INSTANCE * my, int * params ) +{ + INSTANCE * ptr = first_instance, ** ctx ; + + if ( !params[0] ) + { + LOCDWORD( mod_proc, my, TYPE_SCAN ) = 0 ; + if ( LOCDWORD( mod_proc, my, ID_SCAN ) ) + { + ptr = instance_get( LOCDWORD( mod_proc, my, ID_SCAN ) ) ; + if ( ptr ) ptr = ptr->next ; + } + + while ( ptr ) + { + if (( LOCDWORD( mod_proc, ptr, STATUS ) & ~STATUS_WAITING_MASK ) >= STATUS_RUNNING ) + { + LOCDWORD( mod_proc, my, ID_SCAN ) = LOCDWORD( mod_proc, ptr, PROCESS_ID ) ; + return LOCDWORD( mod_proc, ptr, PROCESS_ID ) ; + } + ptr = ptr->next ; + } + return 0 ; + } + + LOCDWORD( mod_proc, my, ID_SCAN ) = 0 ; + /* Check if already in scan by type and we reach limit */ + ctx = ( INSTANCE ** ) LOCADDR( mod_proc, my, CONTEXT ); +/* + if ( !*ctx && LOCDWORD( mod_proc, my, TYPE_SCAN ) ) + { + LOCDWORD( mod_proc, my, TYPE_SCAN ) = 0; + return 0; + } +*/ + /* Check if type change from last call */ + if ( LOCDWORD( mod_proc, my, TYPE_SCAN ) != params[0] ) + { + *ctx = NULL; + LOCDWORD( mod_proc, my, TYPE_SCAN ) = params[0]; + } + + while ( ( ptr = instance_get_by_type( params[0], ctx ) ) ) + { + if ( /*ptr != my &&*/ ( LOCDWORD( mod_proc, ptr, STATUS ) & ~STATUS_WAITING_MASK ) >= STATUS_RUNNING ) + { + return LOCDWORD( mod_proc, ptr, PROCESS_ID ) ; + } + } + + return 0 ; +} + +/* ----------------------------------------------------------------- */ + +static int modproc_get_status( INSTANCE * my, int * params ) +{ + INSTANCE * i ; + if ( !params[0] || !( i = instance_get( params[0] ) ) ) return 0; + return LOCDWORD( mod_proc, i, STATUS ) ; +} + +/* ----------------------------------------------------------------- */ +/* exports */ +/* ----------------------------------------------------------------- */ + +#include "mod_proc_exports.h" + +/* ----------------------------------------------------------------- */ -- cgit v1.2.3