mirror of
https://github.com/zestydevy/marioparty3.git
synced 2024-11-23 05:19:51 +00:00
bunch of math functions, permuter settings
This commit is contained in:
parent
3cf7517632
commit
0b5c435e9b
8
Makefile
8
Makefile
@ -68,7 +68,7 @@ ENDLINE := \n'
|
||||
### Compiler Options ###
|
||||
|
||||
ASFLAGS := -G 0 -I include -mips3 -mabi=32
|
||||
CFLAGS := -O1 -G0 -mips3 -mgp32 -mfp32
|
||||
CFLAGS := -O1 -G0 -mips3 -mgp32 -mfp32 -Wa,--vr4300mul-off
|
||||
CPPFLAGS := -I include -I $(BUILD_DIR)/include -I src -DF3DEX_GBI_2
|
||||
LDFLAGS := -T undefined_syms.txt -T undefined_funcs.txt -T undefined_funcs_auto.txt -T undefined_syms_auto.txt -T $(LD_SCRIPT) -Map $(LD_MAP) --no-check-sections
|
||||
CFLAGS_CHECK := -fsyntax-only -fsigned-char -nostdinc -fno-builtin -D CC_CHECK\
|
||||
@ -86,9 +86,7 @@ DEPENDS := $(OBJECTS:=.d)
|
||||
|
||||
### Targets ###
|
||||
|
||||
#build/src/libultra/os/%.o: CFLAGS := -O2 $(CFLAGSCOMMON)
|
||||
#build/src/libultra/libc/%.o: CFLAGS := -O2 $(CFLAGSCOMMON)
|
||||
#build/src/lib/%.o: CFLAGS := -O2 $(CFLAGSCOMMON)
|
||||
build/src/libhmath/%.o: CFLAGS := -O2 -G0 -mips3 -mgp32 -mfp32 -ffast-math
|
||||
|
||||
all: $(ROM)
|
||||
|
||||
@ -112,8 +110,6 @@ split:
|
||||
|
||||
test: $(ROM)
|
||||
$(V)$(EMULATOR) $<
|
||||
|
||||
export VR4300MUL := OFF
|
||||
# Compile .c files with kmc gcc (use strip to fix objects so that they can be linked with modern gnu ld)
|
||||
$(BUILD_DIR)/src/%.c.o: src/%.c
|
||||
@$(PRINT)$(GREEN)Compiling C file: $(ENDGREEN)$(BLUE)$<$(ENDBLUE)$(ENDLINE)
|
||||
|
@ -3,18 +3,13 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "process.h"
|
||||
#include "math.h"
|
||||
|
||||
#define MAX_PLAYERS 4
|
||||
|
||||
#define OS_K0_TO_PHYSICAL(x) (u32)(((char *)(x)-0x80000000))
|
||||
#define OS_PHYSICAL_TO_K0(x) (void *)(((u32)(x)+0x80000000))
|
||||
|
||||
typedef struct {
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
} HuVec3F;
|
||||
|
||||
typedef struct objectt {
|
||||
/*0x00*/ struct objectt *prev;
|
||||
/*0x04*/ struct objectt *next;
|
||||
|
@ -1,8 +1,22 @@
|
||||
#ifndef _MATH_H_
|
||||
#define _MATH_H_
|
||||
|
||||
#include "PR/ultratypes.h"
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
typedef struct {
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
} HuVec3F;
|
||||
|
||||
typedef struct {
|
||||
s32 x;
|
||||
s32 y;
|
||||
s32 z;
|
||||
} HuVec3I;
|
||||
|
||||
// TODO: Where are these in libultra, if anywhere?
|
||||
float sinf(float);
|
||||
//double sin(double);
|
||||
@ -10,5 +24,11 @@ float cosf(float);
|
||||
//double cos(double);
|
||||
|
||||
float sqrtf(float);
|
||||
float HuSqrtf(float x);
|
||||
|
||||
void HuVecCopyXYZ(HuVec3F * out, f32 x, f32 y, f32 z);
|
||||
void HuVecCopy3F(HuVec3F * out, HuVec3F * a);
|
||||
f32 HuVecGetLengthSqr3F(HuVec3F * vec);
|
||||
f32 HuVecGetLength3F(HuVec3F * vec);
|
||||
|
||||
#endif
|
||||
|
@ -72,6 +72,7 @@ segments:
|
||||
- [0x47D60, asm]
|
||||
- [0x4B120, asm]
|
||||
- [0x4BF40, asm]
|
||||
- [0x4E010, asm, profiler]
|
||||
- [0x4E5A0, c, rom]
|
||||
- [0x4E800, asm]
|
||||
- [0x4F720, c, "process"]
|
||||
@ -310,10 +311,12 @@ segments:
|
||||
- [0x88440, asm]
|
||||
- [0x88460, asm]
|
||||
- [0x88710, asm]
|
||||
- [0x88830, asm]
|
||||
- [0x88CE0, asm]
|
||||
- [0x88CF0, asm]
|
||||
- [0x88D50, asm]
|
||||
- [0x88830, asm] # last libultra scope
|
||||
- [0x88CE0, c, libhmath/sqrtf]
|
||||
- [0x88CF0, c, libhmath/vecmag]
|
||||
- [0x88D50, c, libhmath/vecnorm]
|
||||
- [0x88DE0, c, libhmath/vecdot]
|
||||
- [0x88E10, asm]
|
||||
- [0x890B0, asm]
|
||||
- [0x89120, asm]
|
||||
- [0x89510, asm]
|
||||
@ -325,15 +328,20 @@ segments:
|
||||
- [0x8A4A0, asm]
|
||||
- [0x8A4D0, asm]
|
||||
- [0x8A580, asm]
|
||||
- [0x8A610, asm]
|
||||
- [0x8A640, asm]
|
||||
- [0x8A670, asm]
|
||||
- [0x8A6B0, asm]
|
||||
- [0x8A6F0, asm]
|
||||
- [0x8A770, asm]
|
||||
- [0x8A830, asm]
|
||||
- [0x8A860, asm]
|
||||
- [0x8A890, asm]
|
||||
- [0x8A610, c, libhmath/veccopy]
|
||||
- [0x8A640, c, libhmath/vecneg]
|
||||
- [0x8A670, c, libhmath/vecadd]
|
||||
- [0x8A6B0, c, libhmath/vecsub]
|
||||
- [0x8A6F0, c, libhmath/vecmuls]
|
||||
- [0x8A720, c, libhmath/vecadds]
|
||||
- [0x8A770, c, libhmath/veclinc]
|
||||
- [0x8A830, c, libhmath/vecmags3f]
|
||||
- [0x8A860, c, libhmath/vecmag3f]
|
||||
- [0x8A890, c, libhmath/vecnorm3f]
|
||||
- [0x8A920, c, libhmath/vecdist]
|
||||
- [0x8A9B0, c, libhmath/vecdot3f]
|
||||
- [0x8A9E0, c, libhmath/veccross]
|
||||
- [0x8AA30, c, libhmath/veceq]
|
||||
- [0x8AA90, asm]
|
||||
- [0x8AC30, asm]
|
||||
- [0x8AC70, asm]
|
||||
|
13
permuter_settings.toml
Normal file
13
permuter_settings.toml
Normal file
@ -0,0 +1,13 @@
|
||||
compiler_command = "tools/gcc_2.7.2/gcc -w -Iinclude -Isrc -D_LANGUAGE_C -D_FINALROM -DVERSION=us -DF3DEX_GBI_2 -D_MIPS_SZLONG=32 -nostdinc -c -G0 -O3 -x c -B tools/gcc_2.7.2/ -Wmissing-braces -Wimplicit -Wredundant-decls -Wstrict-prototypes -DPERMUTER -fforce-addr"
|
||||
|
||||
assembler_command = "mips-linux-gnu-as -EB -march=vr4300 -mtune=vr4300 -Iinclude"
|
||||
|
||||
compiler_type = "gcc"
|
||||
|
||||
[preserve_macros]
|
||||
"gs?[DS]P.*" = "void"
|
||||
OVERRIDE_FLAG_CHECK = "int"
|
||||
OS_K0_TO_PHYSICAL = "int"
|
||||
"G_.*" = "int"
|
||||
"TEXEL.*" = "int"
|
||||
PRIMITIVE = "int"
|
5
src/libhmath/sqrtf.c
Normal file
5
src/libhmath/sqrtf.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "common.h"
|
||||
|
||||
f32 HuSqrtf(f32 x) {
|
||||
return sqrtf(x);
|
||||
}
|
14
src/libhmath/vecadd.c
Normal file
14
src/libhmath/vecadd.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecAdd(HuVec3F * out, HuVec3F * a, HuVec3F * b)
|
||||
{
|
||||
float x = a->x + b->x;
|
||||
float y = a->y + b->y;
|
||||
float z = a->z + b->z;
|
||||
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
||||
|
14
src/libhmath/vecadds.c
Normal file
14
src/libhmath/vecadds.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecAddScaled(HuVec3F * out, HuVec3F * a, f32 scalar, HuVec3F * b)
|
||||
{
|
||||
float x = a->x + (scalar * b->x);
|
||||
float y = a->y + (scalar * b->y);
|
||||
float z = a->z + (scalar * b->z);
|
||||
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
||||
|
15
src/libhmath/veccopy.c
Normal file
15
src/libhmath/veccopy.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecCopyXYZ(HuVec3F * out, f32 x, f32 y, f32 z)
|
||||
{
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
||||
|
||||
void HuVecCopy3F(HuVec3F * out, HuVec3F * a)
|
||||
{
|
||||
*out = *a;
|
||||
}
|
||||
|
15
src/libhmath/veccross.c
Normal file
15
src/libhmath/veccross.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "math.h"
|
||||
|
||||
void HuVecCross(HuVec3F * out, HuVec3F * a, HuVec3F * b)
|
||||
{
|
||||
f32 vector1Y = a->y;
|
||||
f32 vector2Z = b->z;
|
||||
f32 vector1Z = a->z;
|
||||
f32 vector2Y = b->y;
|
||||
f32 vector2X = b->x;
|
||||
f32 vector1X = a->x;
|
||||
|
||||
out->x = (vector1Y * vector2Z) - (vector1Z * vector2Y);
|
||||
out->y = (vector1Z * vector2X) - (vector1X * vector2Z);
|
||||
out->z = (vector1X * vector2Y) - (vector1Y * vector2X);
|
||||
}
|
37
src/libhmath/vecdist.c
Normal file
37
src/libhmath/vecdist.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
// this matches, but the entire file needs to have inlined assembly for the mulmul fix to work
|
||||
#ifdef NONMATCHING
|
||||
f32 _HuVecDistanceSqr(HuVec3F * a, HuVec3F * b)
|
||||
{
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
|
||||
x = a->x - b->x;
|
||||
y = a->y - b->y;
|
||||
z = a->z - b->z;
|
||||
|
||||
return (x * x) + (y * y) + (z * z);
|
||||
}
|
||||
#else
|
||||
INCLUDE_ASM(f32, "libhmath/vecdist", HuVecDistanceSqr, HuVec3F * a, HuVec3F * b);
|
||||
#endif
|
||||
|
||||
// https://decomp.me/scratch/02P6S
|
||||
// // the original output has the function prologue near the end rather than the start
|
||||
#ifdef NONMATCHING
|
||||
f32 _HuVecDistance(HuVec3F * arg0, HuVec3F * arg1) {
|
||||
f32 temp_f0;
|
||||
f32 temp_f12;
|
||||
f32 temp_f2;
|
||||
|
||||
temp_f0 = arg0->x - arg1->x;
|
||||
temp_f2 = arg0->y - arg1->y;
|
||||
temp_f12 = arg0->z - arg1->z;
|
||||
return HuSqrtf((temp_f0 * temp_f0) + (temp_f2 * temp_f2) + (temp_f12 * temp_f12));
|
||||
}
|
||||
#else
|
||||
INCLUDE_ASM(f32, "libhmath/vecdist", HuVecDistance, HuVec3F * a, HuVec3F * b);
|
||||
#endif
|
7
src/libhmath/vecdot.c
Normal file
7
src/libhmath/vecdot.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "common.h"
|
||||
|
||||
f32 HuVecDotProduct(f32 aX, f32 aY, f32 aZ, f32 bX, f32 bY, f32 bZ)
|
||||
{
|
||||
return (aX * bX) + (aY * bY) + (aZ * bZ);
|
||||
}
|
||||
|
6
src/libhmath/vecdot3f.c
Normal file
6
src/libhmath/vecdot3f.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "math.h"
|
||||
|
||||
f32 HuVecDot3F(HuVec3F * a, HuVec3F * b)
|
||||
{
|
||||
return (a->x * b->x) + (a->y * b->y) + (a->z * b->z);
|
||||
}
|
9
src/libhmath/veceq.c
Normal file
9
src/libhmath/veceq.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
s32 HuVecIsEqual(HuVec3F * a, HuVec3F * b) {
|
||||
if ((a->x == b->x) && (a->y == b->y) && (a->z == b->z)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
33
src/libhmath/veclinc.c
Normal file
33
src/libhmath/veclinc.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecLinearComb(HuVec3F * out, f32 scale, HuVec3F * a, f32 arg3, HuVec3F * b)
|
||||
{
|
||||
float x = (scale * a->x) + (arg3 * b->x);
|
||||
float y = (scale * a->y) + (arg3 * b->y);
|
||||
float z = (scale * a->z) + (arg3 * b->z);
|
||||
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
||||
|
||||
void HuVecLinearComb2D(HuVec3F * out, HuVec3F * scale, HuVec3F * a, HuVec3F * b)
|
||||
{
|
||||
f32 scaleX;
|
||||
f32 scaleY;
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
|
||||
scaleX = scale->x;
|
||||
scaleY = scale->y;
|
||||
|
||||
x = (scaleX * a->x) + (scaleY * b->x);
|
||||
y = (scaleX * a->y) + (scaleY * b->y);
|
||||
z = (scaleX * a->z) + (scaleY * b->z);
|
||||
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
14
src/libhmath/vecmag.c
Normal file
14
src/libhmath/vecmag.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <PR/ultratypes.h>
|
||||
#include "math.h"
|
||||
|
||||
f32 HuSqrtf(f32);
|
||||
f32 HuVecGetLengthSqr(f32 arg0, f32 arg1, f32 arg2);
|
||||
f32 HuVecGetLength(f32 arg0, f32 arg1, f32 arg2);
|
||||
|
||||
f32 HuVecGetLengthSqr(f32 arg0, f32 arg1, f32 arg2) {
|
||||
return (arg0 * arg0) + (arg1 * arg1) + (arg2 * arg2);
|
||||
}
|
||||
|
||||
f32 mulHuVecGetLength(f32 arg0, f32 arg1, f32 arg2) {
|
||||
return HuSqrtf(HuVecGetLengthSqr(arg0, arg1, arg2));
|
||||
}
|
7
src/libhmath/vecmag3f.c
Normal file
7
src/libhmath/vecmag3f.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
float HuVecGetLength3F(HuVec3F * vec)
|
||||
{
|
||||
return HuSqrtf(HuVecGetLengthSqr3F(vec));
|
||||
}
|
16
src/libhmath/vecmags3f.c
Normal file
16
src/libhmath/vecmags3f.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
f32 HuVecGetLengthSqr3F(HuVec3F * vec)
|
||||
{
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
z = vec->z;
|
||||
|
||||
return (x * x) + (y * y) + (z * z);
|
||||
}
|
||||
|
13
src/libhmath/vecmuls.c
Normal file
13
src/libhmath/vecmuls.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecMulScalar(HuVec3F * out, f32 scalar, HuVec3F * a)
|
||||
{
|
||||
float x = scalar * a->x;
|
||||
float y = scalar * a->y;
|
||||
float z = scalar * a->z;
|
||||
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
14
src/libhmath/vecneg.c
Normal file
14
src/libhmath/vecneg.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecNeg(HuVec3F * out, HuVec3F * a) {
|
||||
|
||||
float x = -a->x;
|
||||
float y = -a->y;
|
||||
float z = -a->z;
|
||||
|
||||
out->x = x;
|
||||
out->y = y;
|
||||
out->z = z;
|
||||
}
|
||||
|
19
src/libhmath/vecnorm.c
Normal file
19
src/libhmath/vecnorm.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecNormalize(f32 * x, f32 * y, f32 * z)
|
||||
{
|
||||
f32 oldX;
|
||||
f32 oldY;
|
||||
f32 oldZ;
|
||||
f32 invMag;
|
||||
|
||||
oldX = *x;
|
||||
oldY = *y;
|
||||
oldZ = *z;
|
||||
invMag = 1.0f / HuSqrtf((oldX * oldX) + (oldY * oldY) + (oldZ * oldZ));
|
||||
|
||||
*x *= invMag;
|
||||
*y *= invMag;
|
||||
*z *= invMag;
|
||||
}
|
25
src/libhmath/vecnorm3f.c
Normal file
25
src/libhmath/vecnorm3f.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
// https://decomp.me/scratch/6UMIQ
|
||||
// the original output has the function prologue near the end rather than the start
|
||||
#ifdef NONMATCHING
|
||||
void _HuVecNormalize3F(HuVec3F * vec)
|
||||
{
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
f32 invMag;
|
||||
|
||||
x = vec->x;
|
||||
y = vec->y;
|
||||
z = vec->z;
|
||||
invMag = 1.0f / HuSqrtf((x * x) + (y * y) + (z * z));
|
||||
|
||||
vec->x = invMag * x;
|
||||
vec->y = invMag * y;
|
||||
vec->z = invMag * z;
|
||||
}
|
||||
#else
|
||||
INCLUDE_ASM(void, "libhmath/vecnorm3f", HuVecNormalize3F, HuVec3F * vec);
|
||||
#endif
|
14
src/libhmath/vecsub.c
Normal file
14
src/libhmath/vecsub.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
|
||||
void HuVecSubtract(HuVec3F * dest, HuVec3F * a, HuVec3F * b) {
|
||||
|
||||
|
||||
float x = a->x - b->x;
|
||||
float y = a->y - b->y;
|
||||
float z = a->z - b->z;
|
||||
|
||||
dest->x = x;
|
||||
dest->y = y;
|
||||
dest->z = z;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
#include "GateGuy.h"
|
||||
#include "math.h"
|
||||
|
||||
void func_801059D0_3D8AC0(void) {
|
||||
D_800CDD58 = 1;
|
||||
@ -142,10 +143,10 @@ void* func_80106740_3D9830(s32 arg0) {
|
||||
return temp_v0;
|
||||
}
|
||||
|
||||
void func_801067D4_3D98C4(object* arg0, s32 arg1) {
|
||||
void func_801067D4_3D98C4(object* arg0, HuVec3F * arg1) {
|
||||
func_800D8E88();
|
||||
func_8001C814_1D414(*arg0->unk3C->unk40, 3, 0);
|
||||
func_80089A20_8A620(&arg0->coords, arg1);
|
||||
HuVecCopy3F(&arg0->coords, arg1);
|
||||
}
|
||||
|
||||
INCLUDE_ASM(s32, "overlays/board_gate_guy/3D8AC0", func_80106828_3D9918);
|
||||
|
@ -12,4 +12,4 @@ extern board_overlay_entrypoint D_80105AE0_3D8A70[];
|
||||
void func_801059A0_3D8930(void) {
|
||||
//func_800359E0_365E0 is ExecBoardScene from mp1
|
||||
func_800359E0_365E0(D_80105AE0_3D8A70, D_800A1764_A2364);
|
||||
}
|
||||
}
|
@ -450,4 +450,27 @@ guPerspective = 0x8007B010;
|
||||
guNormalize = 0x80082B00;
|
||||
gCurrentPlayerIndex = 0x800CD067;
|
||||
guLookAtF = 0x80088210;
|
||||
guLookAt = 0x80079800;
|
||||
guLookAt = 0x80079800;
|
||||
HuSqrtf = 0x800880E0;
|
||||
|
||||
HuVecGetLengthSqr = 0x800880F4;
|
||||
HuVecGetLength = 0x80088120;
|
||||
HuVecNormalize = 0x80088150;
|
||||
HuVecDotProduct = 0x800881E0;
|
||||
HuVecCopyXYZ = 0x80089A10;
|
||||
HuVecCopy3F = 0x80089A20;
|
||||
HuVecNeg = 0x80089A40;
|
||||
HuVecAdd = 0x80089A70;
|
||||
HuVecSubtract = 0x80089AB0;
|
||||
HuVecMulScalar = 0x80089AF0;
|
||||
HuVecAddScaled = 0x80089B20;
|
||||
HuVecLinearComb = 0x80089B70;
|
||||
HuVecLinearComb2D = 0x80089BD0;
|
||||
HuVecGetLengthSqr3F = 0x80089C30;
|
||||
HuVecGetLength3F = 0x80089C60;
|
||||
HuVecNormalize3F = 0x80089C90;
|
||||
HuVecDistanceSqr = 0x80089D20;
|
||||
HuVecDistance = 0x80089D60;
|
||||
HuVecDot3F = 0x80089DB0;
|
||||
HuVecCross = 0x80089DE0;
|
||||
HuVecIsEqual = 0x80089E30;
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user