mirror of
https://github.com/open-goal/jak-project
synced 2026-07-08 14:36:52 -04:00
[ckernel] add remaining jak2 functions (#1611)
This commit is contained in:
@@ -335,7 +335,6 @@ int InitMachine() {
|
||||
// MsgErr("dkernel: !init pad\n");
|
||||
// }
|
||||
|
||||
// do this always
|
||||
if (MasterDebug) { // connect to GOAL compiler
|
||||
InitGoalProto();
|
||||
}
|
||||
|
||||
@@ -382,9 +382,9 @@ int InitMachine() {
|
||||
// if (scePadInit(0) != 1) {
|
||||
// MsgErr("dkernel: !init pad\n");
|
||||
// }
|
||||
// if (MasterDebug != 0) {
|
||||
InitGoalProto();
|
||||
// }
|
||||
if (MasterDebug) {
|
||||
InitGoalProto();
|
||||
}
|
||||
|
||||
printf("InitSound\n");
|
||||
InitSound();
|
||||
@@ -410,12 +410,11 @@ int InitMachine() {
|
||||
*/
|
||||
int ShutdownMachine() {
|
||||
Msg(6, "kernel: machine shutdown (reason %d)\n", MasterExit);
|
||||
ASSERT(false);
|
||||
/*
|
||||
|
||||
StopIOP();
|
||||
ShutdownSound();
|
||||
CloseListener();
|
||||
*/
|
||||
|
||||
ShutdownGoalProto();
|
||||
|
||||
// OpenGOAL only - kill ps2 VM
|
||||
|
||||
@@ -352,7 +352,7 @@ s32 format_impl_jak2(uint64_t* args) {
|
||||
case 'p': {
|
||||
*output_ptr = 0;
|
||||
s8 arg0 = argument_data[0].data[0];
|
||||
u32 in = arg_regs[arg_reg_idx++];
|
||||
u64 in = arg_regs[arg_reg_idx++];
|
||||
if (arg0 == -1) {
|
||||
jak2::print_object(in);
|
||||
} else {
|
||||
@@ -373,7 +373,7 @@ s32 format_impl_jak2(uint64_t* args) {
|
||||
case 'i': {
|
||||
*output_ptr = 0;
|
||||
s8 arg0 = argument_data[0].data[0];
|
||||
u32 in = arg_regs[arg_reg_idx++];
|
||||
u64 in = arg_regs[arg_reg_idx++];
|
||||
if (arg0 == -1) {
|
||||
inspect_object(in);
|
||||
} else {
|
||||
@@ -522,7 +522,17 @@ s32 format_impl_jak2(uint64_t* args) {
|
||||
output_ptr++;
|
||||
|
||||
if (original_dest == s7.offset + FIX_SYM_TRUE) {
|
||||
// do nothing, we're done
|
||||
// #t means to put it in the print buffer
|
||||
|
||||
// change for Jak 2: if we are disk-booting and do a (format #t, immediately flush to stdout.
|
||||
// we'd get these eventually in ClearPending, but for some reason they flush these here.
|
||||
// This is nicer because we may crash in between here and flushing the print buffer.
|
||||
if (DiskBoot) {
|
||||
printf("%s", PrintPendingLocal3);
|
||||
fflush(stdout);
|
||||
PrintPending = make_ptr(PrintPendingLocal2).cast<u8>();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else if (original_dest == s7.offset + FIX_SYM_FALSE) {
|
||||
// #f means print to new string
|
||||
|
||||
@@ -870,13 +870,77 @@ Ptr<Type> set_fixed_type(u32 offset,
|
||||
return symbol_value;
|
||||
}
|
||||
|
||||
static bool in_valid_memory_for_new_type(u32 addr) {
|
||||
if (SymbolTable2.offset <= addr && addr < 0x8000000) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (addr < 0x100000 && addr >= 0x84000) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_valid_type(u32 addr) {
|
||||
if ((addr & 7) != 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*Ptr<u32>(addr - 4) != u32_in_fixed_sym(FIX_SYM_TYPE_TYPE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/*!
|
||||
* New method of type. A GOAL (deftype) will end up calling this method.
|
||||
* Internally does an intern.
|
||||
*/
|
||||
u64 new_type(u32 symbol, u32 parent, u64 flags) {
|
||||
ASSERT(false); // nyi
|
||||
return 0;
|
||||
u32 n_methods = (flags >> 32) & 0xffff;
|
||||
if (n_methods == 0) {
|
||||
// 12 methods used as default, if the user has not provided us with a number
|
||||
n_methods = 12;
|
||||
}
|
||||
|
||||
// copy methods
|
||||
u32 parent_num_methods = Ptr<Type>(parent)->num_methods;
|
||||
auto new_type_obj =
|
||||
Ptr<Type>(intern_type(sym_to_string(Ptr<Symbol4<u32>>(symbol)).offset, n_methods));
|
||||
u32 original_type_list_value = new_type_obj->memusage_method.offset;
|
||||
Ptr<Function>* child_slots = &(new_type_obj->new_method);
|
||||
Ptr<Function>* parent_slots = &(Ptr<Type>(parent)->new_method);
|
||||
for (u32 i = 0; i < n_methods; i++) {
|
||||
if (i < parent_num_methods) { // bug fix from jak 1
|
||||
child_slots[i] = parent_slots[i];
|
||||
} else {
|
||||
child_slots[i].offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// deal with loading-level types
|
||||
if (u32_in_fixed_sym(FIX_SYM_LOADING_LEVEL) == u32_in_fixed_sym(FIX_SYM_GLOBAL_HEAP)) {
|
||||
// not loading a level
|
||||
|
||||
// we'll consider a type list if it's #f or a valid type
|
||||
if (original_type_list_value && (original_type_list_value == s7.offset ||
|
||||
(in_valid_memory_for_new_type(original_type_list_value) &&
|
||||
is_valid_type(original_type_list_value)))) {
|
||||
printf("case 1 for new_type level types\n");
|
||||
new_type_obj->memusage_method.offset = original_type_list_value;
|
||||
}
|
||||
} else {
|
||||
if (original_type_list_value == 0) {
|
||||
// loading a level, but the type is global
|
||||
MsgWarn("dkernel: loading-level init of type %s, but was interned global (this is okay)\n",
|
||||
sym_to_string(new_type_obj->symbol)->data());
|
||||
} else {
|
||||
printf("case 2 for new_type level types\n");
|
||||
new_type_obj->memusage_method.offset = original_type_list_value;
|
||||
}
|
||||
}
|
||||
|
||||
return set_type_values(new_type_obj, Ptr<Type>(parent), flags).offset;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -897,8 +961,73 @@ u64 type_typep(Ptr<Type> t1, Ptr<Type> t2) {
|
||||
}
|
||||
|
||||
u64 method_set(u32 type_, u32 method_id, u32 method) {
|
||||
ASSERT(false); // nyi
|
||||
return 0;
|
||||
Ptr<Type> type(type_);
|
||||
if (method_id > 127)
|
||||
printf("[METHOD SET ERROR] tried to set method %d\n", method_id);
|
||||
|
||||
auto existing_method = type->get_method(method_id).offset;
|
||||
|
||||
if (method == 1) {
|
||||
method = 0;
|
||||
} else if (method == 0) {
|
||||
return 0;
|
||||
} else if (method == 2) {
|
||||
method = type->parent->get_method(method_id).offset;
|
||||
printf("[Method Set] got 2, inheriting\n");
|
||||
}
|
||||
|
||||
// do the set
|
||||
type->get_method(method_id).offset = method;
|
||||
|
||||
// now, propagate to children
|
||||
// we don't track children directly, so we end up having to iterate the whole symbol to find all
|
||||
// types. This is slow, so we only do it in some cases
|
||||
|
||||
// the condition is either setting *enable-method-set* in GOAL, or if we're debugging without the
|
||||
// disk boot. The point of doing this in debug is just to print warning messages.
|
||||
if (*EnableMethodSet || (!FastLink && MasterDebug && !DiskBoot)) {
|
||||
auto sym = Ptr<Symbol4<Ptr<Type>>>(s7.offset);
|
||||
for (; sym.offset < LastSymbol.offset; sym.offset += 4) {
|
||||
auto sym_value = sym->value();
|
||||
if (in_valid_memory_for_new_type(sym_value.offset) && (sym_value.offset & 7) == 4 &&
|
||||
*Ptr<u32>(sym_value.offset - 4) == u32_in_fixed_sym(FIX_SYM_TYPE_TYPE) &&
|
||||
method_id < sym_value->num_methods &&
|
||||
sym_value->get_method(method_id).offset == existing_method &&
|
||||
type_typep(sym_value, type) != s7.offset) {
|
||||
if (FastLink != 0) {
|
||||
printf("************ WARNING **************\n");
|
||||
printf("method %d of %s redefined - you must define class heirarchies in order now\n",
|
||||
method_id, sym_to_string(sym)->data());
|
||||
printf("***********************************\n");
|
||||
}
|
||||
// todo remove once checked
|
||||
printf("doing method set: %s %d\n", sym_to_string(sym)->data(), method_id);
|
||||
sym_value->get_method(method_id).offset = method;
|
||||
}
|
||||
}
|
||||
|
||||
sym = Ptr<Symbol4<Ptr<Type>>>(SymbolTable2.offset);
|
||||
for (; sym.offset < s7.offset; sym.offset += 4) {
|
||||
auto sym_value = sym->value();
|
||||
if (in_valid_memory_for_new_type(sym_value.offset) && (sym_value.offset & 7) == 4 &&
|
||||
*Ptr<u32>(sym_value.offset - 4) == u32_in_fixed_sym(FIX_SYM_TYPE_TYPE) &&
|
||||
method_id < sym_value->num_methods &&
|
||||
sym_value->get_method(method_id).offset == existing_method &&
|
||||
type_typep(sym_value, type) != s7.offset) {
|
||||
if (FastLink != 0) {
|
||||
printf("************ WARNING **************\n");
|
||||
printf("method %d of %s redefined - you must define class heirarchies in order now\n",
|
||||
method_id, sym_to_string(sym)->data());
|
||||
printf("***********************************\n");
|
||||
}
|
||||
// todo remove once checked
|
||||
printf("doing method set: %s %d\n", sym_to_string(sym)->data(), method_id);
|
||||
sym_value->get_method(method_id).offset = method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user