Files
Tyler Wilding d3cc739e43 jakx: Commit existing work from other PRs (#4112)
This attempts to get into master whatever work was done in this PR /
it's earlier PR https://github.com/open-goal/jak-project/pull/3965

I don't want this work to be lost / floating around in massive PRs.

However the changes are:
- switch to ntsc_v1 instead of PAL as the development target, as we have
done for all other games
- remove most of the copied-from-jak2/3 changes as they need to be
confirmed during the decompilation process not just assumed
- avoids committing any changes to `game/kernel/common` as it was not
clear to me if these were changes made in jak x's kernel that were not
properly broken out into it's own functions. We don't want to
accidentally introduce bugs into jak1-3's kernel code.
- in other words, if the change in the kernel only happens in jak x...it
should likely be specific to jak x's kernel, not common.

---------

Co-authored-by: VodBox <dillon@vodbox.io>
Co-authored-by: yodah <greenboyyodah@gmail.com>
2025-12-31 21:08:44 -05:00

143 lines
4.1 KiB
C++

#pragma once
#include <cstring>
#include "common/common_types.h"
#include "common/link_types.h"
#include "game/kernel/common/Ptr.h"
#include "game/kernel/common/kmalloc.h"
#include "game/kernel/common/kscheme.h"
constexpr int LINK_FLAG_OUTPUT_LOAD = 0x1;
constexpr int LINK_FLAG_OUTPUT_TRUE = 0x2;
constexpr int LINK_FLAG_EXECUTE = 0x4;
constexpr int LINK_FLAG_PRINT_LOGIN = 0x8; //! Note, doesn't actually do anything.
constexpr int LINK_FLAG_FORCE_DEBUG = 0x10;
constexpr int LINK_FLAG_FORCE_FAST_LINK = 0x20;
// only used in OpenGOAL
struct SegmentInfo {
uint32_t offset;
uint32_t size;
};
// only used in OpenGOAL
struct ObjectFileHeader {
uint16_t goal_version_major;
uint16_t goal_version_minor;
uint32_t object_file_version;
uint32_t segment_count;
SegmentInfo link_infos[N_SEG];
SegmentInfo code_infos[N_SEG];
uint32_t link_block_length;
};
struct SegmentInfoV5 {
uint32_t relocs; // offset of relocation table
uint32_t data; // offset of segment data
uint32_t size; // segment data size (0 if segment doesn't exist)
uint32_t magic; // always 0
};
void klink_init_globals();
/*!
* Stores the state of the linker. Used for multi-threaded linking, so it can be suspended.
*/
struct link_control {
Ptr<uint8_t> m_object_data; //! points to the start of the object file
Ptr<uint8_t> m_entry; //! points to first code to execute
char m_object_name[64]; //! object file name
int32_t m_object_size; //! object file size
Ptr<kheapinfo> m_heap; //! heap we are putting the object file on
uint32_t m_flags; //! linker configuration
Ptr<uint8_t> m_heap_top; //! where to reset the heap top for clearing temp allocations
bool m_keep_debug; //! keep the debug segment, even if DebugSegment is off?
Ptr<uint8_t> m_link_block_ptr;
uint32_t m_code_size;
Ptr<uint8_t> m_code_start;
uint32_t m_state;
uint32_t m_segment_process;
uint32_t m_version;
int m_heap_gap;
Ptr<uint8_t> m_original_object_location;
Ptr<u8> m_reloc_ptr;
Ptr<u8> m_base_ptr;
Ptr<u8> m_loc_ptr;
int m_table_toggle;
bool m_opengoal;
bool m_busy; // only in jak2, but doesn't hurt to set it in jak 1.
// jak 3 new stuff
bool m_on_global_heap = false;
LinkHeaderV5Core* m_link_hdr = nullptr;
bool m_moved_link_block = false;
int m_n_segments = 0;
SegmentInfoV5* m_link_segments_table = nullptr;
void jak1_jak2_begin(Ptr<uint8_t> object_file,
const char* name,
int32_t size,
Ptr<kheapinfo> heap,
uint32_t flags);
void jak3_begin(Ptr<uint8_t> object_file,
const char* name,
int32_t size,
Ptr<kheapinfo> heap,
uint32_t flags);
void jakx_begin(Ptr<uint8_t> object_file,
const char* name,
int32_t size,
Ptr<kheapinfo> heap,
uint32_t flags);
// was originally "work"
uint32_t jak1_work();
uint32_t jak2_work();
uint32_t jak3_work();
uint32_t jakx_work();
uint32_t jak1_work_v3();
uint32_t jak1_work_v2();
uint32_t jak2_work_v3();
uint32_t jak2_work_v2();
uint32_t jak3_work_v2_v4();
uint32_t jak3_work_v5();
uint32_t jak3_work_opengoal();
uint32_t jakx_work_v2_v4();
uint32_t jakx_work_v5();
uint32_t jakx_work_opengoal();
void jak1_finish(bool jump_from_c_to_goal);
void jak2_finish(bool jump_from_c_to_goal);
void jak3_finish(bool jump_from_c_to_goal);
void jakx_finish(bool jump_from_c_to_goal);
void reset() {
m_object_data.offset = 0;
m_entry.offset = 0;
memset(m_object_name, 0, sizeof(m_object_name));
m_object_size = 0;
m_heap.offset = 0;
m_flags = 0;
m_heap_top.offset = 0;
m_keep_debug = false;
m_link_block_ptr.offset = 0;
m_code_size = 0;
m_code_start.offset = 0;
m_state = 0;
m_segment_process = 0;
m_version = 0;
m_busy = false;
}
};
Ptr<u8> c_symlink2(Ptr<u8> objData, Ptr<u8> linkObj, Ptr<u8> relocTable);
extern link_control saved_link_control;
extern Ptr<Function> gfunc_774; // actually 807 in jak2.