summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/atomic.h4
-rw-r--r--src/common/cbasetypes.h12
-rw-r--r--src/common/grfio.c18
-rw-r--r--src/common/mmo.h15
-rw-r--r--src/map/battle.c3
-rw-r--r--src/map/script.c54
-rw-r--r--src/map/script.h3
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HookingPoints.inc1
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Hooks.inc25
10 files changed, 108 insertions, 31 deletions
diff --git a/src/common/atomic.h b/src/common/atomic.h
index c2227a9d4..8c01943e7 100644
--- a/src/common/atomic.h
+++ b/src/common/atomic.h
@@ -87,7 +87,9 @@ forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 v
#elif defined(__GNUC__)
-#if !defined(__x86_64__) && !defined(__i386__)
+// The __sync functions are available on x86 or ARMv6+
+#if !defined(__x86_64__) && !defined(__i386__) \
+ && ( !defined(__ARM_ARCH_VERSION__) || __ARM_ARCH_VERSION__ < 6 )
#error Your Target Platfrom is not supported
#endif
diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h
index 654334a9b..f44e80413 100644
--- a/src/common/cbasetypes.h
+++ b/src/common/cbasetypes.h
@@ -42,6 +42,18 @@
#define __DARWIN__
#endif
+// Standardize the ARM platform version, if available (the only values we're interested in right now are >= ARMv6)
+#if defined(__ARMV6__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \
+ || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) // gcc ARMv6
+#define __ARM_ARCH_VERSION__ 6
+#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__) // gcc ARMv7
+#define __ARM_ARCH_VERSION__ 7
+#elif defined(_M_ARM) // MSVC
+#define __ARM_ARCH_VERSION__ _M_ARM
+#else
+#define __ARM_ARCH_VERSION__ 0
+#endif
+
// Necessary for __NetBSD_Version__ (defined as VVRR00PP00) on NetBSD
#ifdef __NETBSD__
#include <sys/param.h>
diff --git a/src/common/grfio.c b/src/common/grfio.c
index 57e8a5187..bde0ed720 100644
--- a/src/common/grfio.c
+++ b/src/common/grfio.c
@@ -21,15 +21,15 @@
// file entry table struct
//----------------------------
typedef struct _FILELIST {
- int srclen; // compressed size
- int srclen_aligned;
- int declen; // original size
- int srcpos; // position of entry in grf
- int next; // index of next filelist entry with same hash (-1: end of entry chain)
- char type;
- char fn[128-4*5]; // file name
- char* fnd; // if the file was cloned, contains name of original file
- char gentry; // read grf file select
+ int srclen; ///< compressed size
+ int srclen_aligned;
+ int declen; ///< original size
+ int srcpos; ///< position of entry in grf
+ int next; ///< index of next filelist entry with same hash (-1: end of entry chain)
+ char type;
+ char fn[128-4*5]; ///< file name
+ char *fnd; ///< if the file was cloned, contains name of original file
+ int8 gentry; ///< read grf file select
} FILELIST;
#define FILELIST_TYPE_FILE 0x01 // entry is a file
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 2b66c516c..cf3933d40 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -334,14 +334,13 @@ struct s_homunculus { //[orn]
unsigned int exp;
short rename_flag;
short vaporize; //albator
- int str ;
- int agi ;
- int vit ;
- int int_ ;
- int dex ;
- int luk ;
-
- char spiritball; //for homun S [lighta]
+ int str;
+ int agi;
+ int vit;
+ int int_;
+ int dex;
+ int luk;
+ int8 spiritball; //for homun S [lighta]
};
struct s_mercenary {
diff --git a/src/map/battle.c b/src/map/battle.c
index 40f3d2482..24f39a35d 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -4657,6 +4657,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
#endif
switch(skill_id){
case SR_GATEOFHELL:
+ #ifdef RENEWAL
+ RE_SKILL_REDUCTION();
+ #endif // RENEWAL
if (wd.dmg_lv != ATK_FLEE)
ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
else
diff --git a/src/map/script.c b/src/map/script.c
index bef5f37e0..fef25b927 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3130,8 +3130,7 @@ struct script_data* push_copy(struct script_stack* stack, int pos) {
/// Removes the values in indexes [start,end[ from the stack.
/// Adjusts all stack pointers.
-void pop_stack(struct script_state* st, int start, int end)
-{
+void pop_stack(struct script_state* st, int start, int end) {
struct script_stack* stack = st->stack;
struct script_data* data;
int i;
@@ -3153,6 +3152,10 @@ void pop_stack(struct script_state* st, int start, int end)
{
struct script_retinfo* ri = data->u.ri;
if( ri->scope.vars ) {
+ // Note: This is necessary evern if we're also doing it in run_func
+ // (in the RETFUNC block) because not all functions return. If a
+ // function (or a sub) has an 'end' or a 'close', it'll reach this
+ // block with its scope vars still to be freed.
script->free_vars(ri->scope.vars);
ri->scope.vars = NULL;
}
@@ -3224,6 +3227,8 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
st = ers_alloc(script->st_ers, struct script_state);
st->stack = ers_alloc(script->stack_ers, struct script_stack);
+ st->pending_refs = NULL;
+ st->pending_ref_count = 0;
st->stack->sp = 0;
st->stack->sp_max = 64;
CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max);
@@ -3280,6 +3285,12 @@ void script_free_state(struct script_state* st) {
}
}
st->pos = -1;
+ if (st->pending_ref_count > 0) {
+ while (st->pending_ref_count > 0)
+ aFree(st->pending_refs[--st->pending_ref_count]);
+ aFree(st->pending_refs);
+ st->pending_refs = NULL;
+ }
idb_remove(script->st_db, st->id);
ers_free(script->st_ers, st);
if( --script->active_scripts == 0 ) {
@@ -3288,6 +3299,19 @@ void script_free_state(struct script_state* st) {
}
}
+/**
+ * Adds a pending reference entry to the current script.
+ *
+ * @see struct script_state::pending_refs
+ *
+ * @param st[in] Script state.
+ * @param ref[in] Reference to be added.
+ */
+void script_add_pending_ref(struct script_state *st, struct reg_db *ref) {
+ RECREATE(st->pending_refs, struct reg_db*, ++st->pending_ref_count);
+ st->pending_refs[st->pending_ref_count-1] = ref;
+}
+
//
// Main execution unit
//
@@ -4883,7 +4907,10 @@ BUILDIN(callfunc)
st->stack->defsp = st->stack->sp;
st->state = GOTO;
st->stack->scope.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
- st->stack->scope.arrays = i64db_alloc(DB_OPT_BASE);
+ st->stack->scope.arrays = idb_alloc(DB_OPT_BASE);
+
+ if( !st->script->local.vars )
+ st->script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
return true;
}
@@ -4934,7 +4961,7 @@ BUILDIN(callsub)
st->stack->defsp = st->stack->sp;
st->state = GOTO;
st->stack->scope.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
- st->stack->scope.arrays = i64db_alloc(DB_OPT_BASE);
+ st->stack->scope.arrays = idb_alloc(DB_OPT_BASE);
return true;
}
@@ -4977,30 +5004,30 @@ BUILDIN(getarg)
///
/// return;
/// return <value>;
-BUILDIN(return)
-{
+BUILDIN(return) {
if( script_hasdata(st,2) )
{// return value
struct script_data* data;
script_pushcopy(st, 2);
data = script_getdatatop(st, -1);
- if( data_isreference(data) )
- {
+ if( data_isreference(data) ) {
const char* name = reference_getname(data);
- if( name[0] == '.' && name[1] == '@' )
- {// scope variable
+ if( name[0] == '.' && name[1] == '@' ) {
+ // scope variable
if( !data->ref || data->ref->vars == st->stack->scope.vars )
script->get_val(st, data);// current scope, convert to value
if( data->ref && data->ref->vars == st->stack->stack_data[st->stack->defsp-1].u.ri->scope.vars )
data->ref = NULL; // Reference to the parent scope, remove reference pointer
- }
- else if( name[0] == '.' && !data->ref )
- {// script variable, link to current script
+ } else if( name[0] == '.' && !data->ref ) {
+ // script variable without a reference set, link to current script
data->ref = (struct reg_db *)aCalloc(sizeof(struct reg_db), 1);
+ script->add_pending_ref(st, data->ref);
data->ref->vars = st->script->local.vars;
if( !st->script->local.arrays )
st->script->local.arrays = idb_alloc(DB_OPT_BASE);
data->ref->arrays = st->script->local.arrays;
+ } else if ( name[0] == '.' /* && data->ref != NULL */ ) {
+ data->ref = NULL; // Reference to the parent scope's script, remove reference pointer.
}
}
}
@@ -19231,6 +19258,7 @@ void script_defaults(void) {
script->free_vars = script_free_vars;
script->alloc_state = script_alloc_state;
script->free_state = script_free_state;
+ script->add_pending_ref = script_add_pending_ref;
script->run_autobonus = script_run_autobonus;
script->cleararray_pc = script_cleararray_pc;
script->setarray_pc = script_setarray_pc;
diff --git a/src/map/script.h b/src/map/script.h
index ff947bf79..73ba7303e 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -401,6 +401,8 @@ struct hQueueIterator {
struct script_state {
struct script_stack* stack;
+ struct reg_db **pending_refs; ///< References to .vars returned by sub-functions, pending deletion.
+ int pending_ref_count; ///< Amount of pending_refs currently stored.
int start,end;
int pos;
enum e_script_state state;
@@ -589,6 +591,7 @@ struct script_interface {
void (*free_vars) (struct DBMap *var_storage);
struct script_state* (*alloc_state) (struct script_code* rootscript, int pos, int rid, int oid);
void (*free_state) (struct script_state* st);
+ void (*add_pending_ref) (struct script_state *st, struct reg_db *ref);
void (*run_autobonus) (const char *autobonus,int id, int pos);
void (*cleararray_pc) (struct map_session_data* sd, const char* varname, void* value);
void (*setarray_pc) (struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache);
diff --git a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
index fa9b04d39..4f37743f6 100644
--- a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
@@ -4081,6 +4081,8 @@ struct {
struct HPMHookPoint *HP_script_alloc_state_post;
struct HPMHookPoint *HP_script_free_state_pre;
struct HPMHookPoint *HP_script_free_state_post;
+ struct HPMHookPoint *HP_script_add_pending_ref_pre;
+ struct HPMHookPoint *HP_script_add_pending_ref_post;
struct HPMHookPoint *HP_script_run_autobonus_pre;
struct HPMHookPoint *HP_script_run_autobonus_post;
struct HPMHookPoint *HP_script_cleararray_pc_pre;
@@ -9112,6 +9114,8 @@ struct {
int HP_script_alloc_state_post;
int HP_script_free_state_pre;
int HP_script_free_state_post;
+ int HP_script_add_pending_ref_pre;
+ int HP_script_add_pending_ref_post;
int HP_script_run_autobonus_pre;
int HP_script_run_autobonus_post;
int HP_script_cleararray_pc_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
index b90bb6a88..dd8c603d3 100644
--- a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
@@ -2074,6 +2074,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->free_vars, HP_script_free_vars) },
{ HP_POP(script->alloc_state, HP_script_alloc_state) },
{ HP_POP(script->free_state, HP_script_free_state) },
+ { HP_POP(script->add_pending_ref, HP_script_add_pending_ref) },
{ HP_POP(script->run_autobonus, HP_script_run_autobonus) },
{ HP_POP(script->cleararray_pc, HP_script_cleararray_pc) },
{ HP_POP(script->setarray_pc, HP_script_setarray_pc) },
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index 49d276edb..78987f81a 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -52614,6 +52614,31 @@ void HP_script_free_state(struct script_state *st) {
}
return;
}
+void HP_script_add_pending_ref(struct script_state *st, struct reg_db *ref) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_script_add_pending_ref_pre ) {
+ void (*preHookFunc) (struct script_state *st, struct reg_db *ref);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_add_pending_ref_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_add_pending_ref_pre[hIndex].func;
+ preHookFunc(st, ref);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.script.add_pending_ref(st, ref);
+ }
+ if( HPMHooks.count.HP_script_add_pending_ref_post ) {
+ void (*postHookFunc) (struct script_state *st, struct reg_db *ref);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_add_pending_ref_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_add_pending_ref_post[hIndex].func;
+ postHookFunc(st, ref);
+ }
+ }
+ return;
+}
void HP_script_run_autobonus(const char *autobonus, int id, int pos) {
int hIndex = 0;
if( HPMHooks.count.HP_script_run_autobonus_pre ) {