Add files to repository

master
Alec Murphy 1 month ago
parent 0933592092
commit 5a0fa56b11
  1. 41
      Lib/Base.HC
  2. 165
      Lib/DC.HC
  3. 21
      Lib/Debug.HC
  4. 283
      Lib/ELF64.HC
  5. 32
      Lib/Input.HC
  6. 68
      Lib/LibC.HC
  7. 818
      Lib/LibC_old.HC
  8. 24
      Lib/Misc.HC
  9. 17
      Lib/New.HC
  10. 17
      Lib/OS.HC
  11. 8
      Lib/Time.HC
  12. 21
      Load.HC
  13. 1
      Run.HC
  14. 72
      dc.jakt
  15. 8
      include/dc.h
  16. 3
      include/input.h
  17. 2
      include/os.h
  18. 1
      include/time.h
  19. 31
      input.jakt
  20. 27
      libtemple/libtemple.cpp
  21. 10
      main.jakt
  22. 18
      os.jakt
  23. 11
      time.jakt

@ -0,0 +1,41 @@
#define PUSH_SYSV_REGS \
asm {PUSH RCX PUSH RDX PUSH RBX PUSH RBP PUSH RSI PUSH RDI PUSH R8 PUSH R9 PUSH \
R10 PUSH R11 PUSH R12 PUSH R13 PUSH R14 PUSH R15}
#define POP_SYSV_REGS \
asm {POP R15 POP R14 POP R13 POP R12 POP R11 POP R10 POP R9 POP R8 POP RDI POP \
RSI POP RBP POP RBX POP RDX POP RCX}
#define MOV_ANS_RAX asm {MOV [&ans], RAX}
#define MOV_P0_RDI asm {MOV [&p0], RDI}
#define MOV_P1_RSI asm {MOV [&p1], RSI}
#define MOV_P2_RDX asm {MOV [&p2], RDX}
#define MOV_P3_RCX asm {MOV [&p3], RCX}
#define MOV_P4_R8 asm {MOV [&p4], R8}
#define MOV_P5_R9 asm {MOV [&p5], R9}
#define GET_SYSV_ARGS \
MOV_P0_RDI MOV_P1_RSI MOV_P2_RDX MOV_P3_RCX MOV_P4_R8 MOV_P5_R9
I64 p0, p1, p2, p3, p4, p5;
I64 elf_argc;
U8 **elf_argv;
asm {
_ELF_CALL::
PUSH RBP
MOV RBP,RSP
MOV RAX,U64 SF_ARG1[RBP]
MOV RDI,U64 SF_ARG2[RBP]
MOV RSI,U64 SF_ARG3[RBP]
TEST RAX,RAX
JZ @@05
CALL RAX
@@05: POP RBP
RET1 8
}
U0 _main() {
MOV_P0_RDI
CallInd(_ELF_CALL, p0, elf_argc, elf_argv);
UserTaskCont;
}
U0 _exit() { UserTaskCont; }

@ -0,0 +1,165 @@
U0 _Z7dc_blotmmmm() {
// dc_blot(unsigned long, unsigned long, unsigned long, unsigned long)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_blot(0x%08x, %d, %d, 0x%08x)\n", p0, p1, p2, p3);
GrBlot(p0, p1, p2, p3);
POP_SYSV_REGS
}
U0 @dc_copy(CDC *dest, I64 x, I64 y, CDC *src) {
// If position is off-screen, return
if (x > dest->width - 1 || y > dest->height - 1)
return;
// If device context dimensions match, MemCpy and return
if (dest->width_internal == src->width_internal &&
dest->height == src->height) {
MemCpy(dest->body, src->body, dest->width_internal * dest->height);
return;
}
CDC *dc1 = DCAlias(dest);
CDC *dc2 = DCAlias(src);
I64 src_line = 0;
I64 src_row = 0;
I64 clip_y = 0;
// Handle horizontal clipping left
while (x < 0) {
dc2->x0++;
x++;
}
// Handle vertical clipping top
while (y < 0) {
dc2->body += src->width_internal;
dc2->y0++;
y++;
}
// default, clip line to copy as width-left off screen
src_line = src->width - dc2->x0;
if (-dc2->x0 + x + src->width >= dest->width) {
src_line -= ((-dc2->x0 + x + src->width) - dest->width);
}
dc2->body += dc2->x0;
clip_y = y;
while (src_row < (src->height - dc2->y0) && clip_y < dest->height) {
MemCpy(dc1->body + (y * dest->width) + x, dc2->body, src_line);
dc2->body += src->width_internal;
dc1->body += dest->width_internal;
clip_y++;
src_row++;
}
Free(dc2);
Free(dc1);
}
U0 _Z7dc_copymmmm() {
// dc_copy(unsigned long, unsigned long, unsigned long, unsigned long)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_copy(0x%08x, %d, %d, 0x%08x)\n", p0, p1, p2, p3);
@dc_copy(p0, p1, p2, p3);
POP_SYSV_REGS
}
U0 _Z7dc_fillmm() {
// dc_fill(unsigned long, unsigned long)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_fill(0x%08x, %d\n", p0, p1);
DCFill(p0, p1);
POP_SYSV_REGS
}
CDC *@dc_gr_dc_alias(I64 *width, I64 *height) {
// CDC *dc = DCAlias(gr.dc);
CDC *dc = gr.dc;
if (dc) {
*width = dc->width;
*height = dc->height;
}
return dc;
}
U0 _Z14dc_gr_dc_aliasPlS_() {
// dc_gr_dc_alias(long*, long*)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_gr_dc_alias(0x%08x, 0x%08x)\n", p0, p1);
@dc_gr_dc_alias(p0, p1);
POP_SYSV_REGS
}
CDC *@dc_integer_scale(CDC *dc, I64 scale_factor, I64 *dc_width,
I64 *dc_height) {
if (scale_factor < 2)
return dc;
CDC *dc2 = DCNew(dc->width * scale_factor, dc->height * scale_factor);
I64 x;
I64 y;
for (y = 0; y < dc->height; y++)
for (x = 0; x < dc->width; x++) {
dc2->color = GrPeek(dc, x, y);
GrRect(dc2, x * scale_factor, y * scale_factor, scale_factor,
scale_factor);
}
DCDel(dc);
*dc_width = dc2->width;
*dc_height = dc2->height;
return dc2;
}
U0 _Z16dc_integer_scalemlPlS_() {
// dc_integer_scale(unsigned long, long, long*, long*)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_integer_scale(0x%08x, %d, 0x%08x, 0x%08x)\n", p0, p1,
p2, p3);
@dc_integer_scale(p0, p1, p2, p3);
POP_SYSV_REGS
}
CDC *@dc_load_from_file(U8 *filename, I64 *width, I64 *height) {
CDC *dc = GRRead(filename);
if (dc) {
*width = dc->width;
*height = dc->height;
}
return dc;
}
U0 _Z17dc_load_from_filePKcPlS1_() {
// dc_load_from_file(char const*, long*, long*)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_load_from_file(%s, 0x%08x, 0x%08x)\n", p0, p1, p2);
@dc_load_from_file(p0, p1, p2);
POP_SYSV_REGS
}
U0 _Z6dc_newmm() {
// dc_new(unsigned long, unsigned long)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_new(%d, %d)\n", p0, p1);
DCNew(p0, p1);
POP_SYSV_REGS
}
U0 _Z16dc_replace_colormmm() {
// dc_replace_color(unsigned long, unsigned long, unsigned long)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: dc_replace_color(0x%08x, %d, %d)\n", p0, p1, p2);
DCColorChg(p0, p1, p2);
POP_SYSV_REGS
}

@ -0,0 +1,21 @@
class Debug {
Bool enabled;
I64 bookmark;
I64 counter;
};
Debug debug;
debug.bookmark = 0;
debug.counter = 0;
debug.enabled = FALSE;
U0 debug_print(U8 *fmt, ...) {
if (!debug.enabled || debug.counter < debug.bookmark) {
debug.counter++;
return;
}
U8 *buf = StrPrintJoin(NULL, fmt, argc, argv);
"[%05d] %s", debug.counter, buf;
Free(buf);
debug.counter++;
}

@ -0,0 +1,283 @@
#define EI_NIDENT 16
#define EM_X86_64 0x3E
#define ET_EXEC 2
#define ET_DYN 3
class Elf64_Ehdr {
U8 e_ident[EI_NIDENT]; /* Magic number and other info */
U16 e_type; /* Object file type */
U16 e_machine; /* Architecture */
U32 e_version; /* Object file version */
U64 e_entry; /* Entry point virtual address */
U64 e_phoff; /* Program header table file offset */
U64 e_shoff; /* Section header table file offset */
U32 e_flags; /* Processor-specific flags */
U16 e_ehsize; /* ELF header size in bytes */
U16 e_phentsize; /* Program header table entry size */
U16 e_phnum; /* Program header table entry count */
U16 e_shentsize; /* Section header table entry size */
U16 e_shnum; /* Section header table entry count */
U16 e_shstrndx; /* Section header string table index */
};
class Elf64_Shdr {
U32 sh_name; /* Section name (string tbl index) */
U32 sh_type; /* Section type */
U64 sh_flags; /* Section flags */
U64 sh_addr; /* Section virtual addr at execution */
U64 sh_offset; /* Section file offset */
U64 sh_size; /* Section size in bytes */
U32 sh_link; /* Link to another section */
U32 sh_info; /* Additional section information */
U64 sh_addralign; /* Section alignment */
U64 sh_entsize; /* Entry size if section holds table */
};
class Elf64_Sym {
U32 st_name; /* Symbol name (string tbl index) */
U8 st_info; /* Symbol type and binding */
U8 st_other; /* Symbol visibility */
U16 st_shndx; /* Section index */
U64 st_value; /* Symbol value */
U64 st_size; /* Symbol size */
};
class PLT_entry {
U8 pad[0x10];
};
class RELA_entry {
U64 r_offset;
U64 r_info;
I64 r_addend;
};
class Elf {
union {
U8 *u8;
Elf64_Ehdr *ehdr;
} I64 size;
U8 *dynstr;
Elf64_Sym *dynsym;
PLT_entry *plt;
RELA_entry *rela_dyn;
RELA_entry *rela_plt;
Elf64_Sym *strtab;
Elf64_Sym *symtab;
I64 rela_dyn_size;
I64 rela_plt_size;
I64 strtab_size;
I64 symtab_size;
};
U0 (*_start)();
U0 unimplemented_symbol() {
I32 s = 0xDEADF00D;
"Unimplemented symbol: %s\n", s;
while (1)
Sleep(1);
}
Bool is_valid_elf(Elf *elf) {
Bool res = TRUE;
if (MemCmp(elf->u8 + 1, "ELF", 3)) {
debug_print("Invalid signature (not ELF).\n");
res = FALSE;
}
if (elf->ehdr->e_type != ET_EXEC && elf->ehdr->e_type != ET_DYN) {
debug_print("Invalid object file type.\n");
res = FALSE;
}
if (elf->ehdr->e_machine != EM_X86_64) {
debug_print("Invalid architecture.\n");
res = FALSE;
}
return res;
}
U0 process_elf_section_header_table(Elf *elf) {
Elf64_Shdr *shdr = elf->u8 + elf->ehdr->e_shoff;
Elf64_Shdr *shdr_shstrtab = shdr + elf->ehdr->e_shstrndx;
U8 *shstrtab = elf->u8 + shdr_shstrtab->sh_offset;
I64 i = 0;
while (i < elf->ehdr->e_shnum) {
if (!StrCmp(shstrtab + shdr->sh_name, ".symtab")) {
debug_print("found symtab at 0x%08x, size = %d\n", shdr->sh_offset,
shdr->sh_size);
elf->symtab = elf->u8 + shdr->sh_offset;
elf->symtab_size = shdr->sh_size;
}
if (!StrCmp(shstrtab + shdr->sh_name, ".strtab")) {
debug_print("found strtab at 0x%08x, size = %d\n", shdr->sh_offset,
shdr->sh_size);
elf->strtab = elf->u8 + shdr->sh_offset;
elf->strtab_size = shdr->sh_size;
}
if (shdr->sh_addr) {
MemCpy(shdr->sh_addr, elf->u8 + shdr->sh_offset, shdr->sh_size);
if (!StrCmp(shstrtab + shdr->sh_name, ".dynstr"))
elf->dynstr = shdr->sh_addr;
if (!StrCmp(shstrtab + shdr->sh_name, ".dynsym"))
elf->dynsym = shdr->sh_addr;
if (!StrCmp(shstrtab + shdr->sh_name, ".plt"))
elf->plt = shdr->sh_addr;
if (!StrCmp(shstrtab + shdr->sh_name, ".rela.dyn")) {
elf->rela_dyn = shdr->sh_addr;
elf->rela_dyn_size = shdr->sh_size / shdr->sh_entsize;
}
if (!StrCmp(shstrtab + shdr->sh_name, ".rela.plt")) {
elf->rela_plt = shdr->sh_addr;
elf->rela_plt_size = shdr->sh_size / shdr->sh_entsize;
}
debug_print(
"MemCpy section '%s' to physical address 0x%06x, size = %d bytes\n",
shstrtab + shdr->sh_name, shdr->sh_addr, shdr->sh_size);
if (!StrCmp(shstrtab + shdr->sh_name, ".bss")) {
MemSet(shdr->sh_addr, NULL, shdr->sh_size);
debug_print("MemSet section '%s' at physical address 0x%06x to NULL, "
"size = %d bytes\n",
shstrtab + shdr->sh_name, shdr->sh_addr, shdr->sh_size);
}
if (!StrCmp(shstrtab + shdr->sh_name, ".data"))
i = elf->ehdr->e_shnum;
}
shdr++;
i++;
}
}
U0 process_elf_rela_dyn_entries(Elf *elf) {
I64 i;
U8 *entry_name;
RELA_entry *rela_dyn = elf->rela_dyn;
for (i = 0; i < elf->rela_dyn_size; i++) {
entry_name = elf->dynstr + elf->dynsym[(rela_dyn->r_info >> 32)].st_name;
debug_print("rela_dyn->r_offset = %08x\n", rela_dyn->r_offset);
debug_print("entry name = '%s'\n", entry_name);
if (!StrCmp(entry_name, "__libc_start_main")) {
*(rela_dyn->r_offset)(U64 *) = &_main;
debug_print("Set value for .rela.dyn entry '%s' to: &_main\n",
entry_name);
}
if (!StrCmp(entry_name, "stdin")) {
*(rela_dyn->r_offset)(U64 *) = 0;
debug_print("Set value for .rela.dyn entry '%s' to: %d\n", entry_name, 0);
}
if (!StrCmp(entry_name, "stdout")) {
*(rela_dyn->r_offset)(U64 *) = 1;
debug_print("Set value for .rela.dyn entry '%s' to: %d\n", entry_name, 1);
}
if (!StrCmp(entry_name, "stderr")) {
*(rela_dyn->r_offset)(U64 *) = 2;
debug_print("Set value for .rela.dyn entry '%s' to: %d\n", entry_name, 2);
}
rela_dyn++;
}
}
CHashClass *get_symbol_hash_entry(U8 *entry_name) {
I64 i;
CHashSrcSym *sym;
CHashTable *tbl = Fs->hash_table;
while (tbl) {
for (i = 0; i < tbl->mask; i++) {
sym = tbl->body[i];
while (sym) {
if (sym->type == HTT_CLASS)
if (!StrCmp(sym->str, entry_name))
return sym;
sym = sym->next;
}
}
tbl = tbl->next;
}
return NULL;
}
U64 get_symbol_address(U8 *entry_name) {
CHash *h = HashFind(entry_name, Fs->hash_table, Fs->hash_table->mask);
if (!h)
return NULL;
switch (h->type) {
case HTT_GLBL_VAR:
return h(CHashGlblVar *)->data_addr;
break;
case HTT_FUN:
return h(CHashFun *)->exe_addr;
break;
default:
return NULL;
break;
}
return NULL;
}
U0 process_elf_rela_plt_entries(Elf *elf) {
I64 i;
U32 handler;
U32 *patch;
U8 *entry_name;
Bool symbol_exists;
PLT_entry *plt = elf->plt;
RELA_entry *rela_plt = elf->rela_plt;
plt++;
for (i = 0; i < elf->rela_plt_size; i++) {
symbol_exists = FALSE;
entry_name = elf->dynstr + elf->dynsym[(rela_plt->r_info >> 32)].st_name;
handler = MAlloc(sizeof(unimplemented_symbol), Fs->code_heap);
MemCpy(handler, &unimplemented_symbol, sizeof(unimplemented_symbol));
patch = handler + 0x0A;
*patch = entry_name;
PatchJmpRel32(plt, handler);
PatchCallRel32(handler + 0x16, &PrintErr);
PatchCallRel32(handler + 0x21, &_exit);
if (!StrCmp(entry_name, "__libc_start_main")) {
symbol_exists = TRUE;
PatchJmpRel32(plt, &_main);
debug_print("Set value for .rela.plt entry '%s' to &_main\n", entry_name);
}
if (get_symbol_address(entry_name)) {
symbol_exists = TRUE;
PatchJmpRel32(plt, get_symbol_address(entry_name));
debug_print("Set value for .rela.plt entry '%s' to &%s\n", entry_name,
entry_name);
}
if (!symbol_exists)
debug_print(
"Set value for .rela.plt entry '%s' to &unimplemented_symbol\n",
entry_name);
rela_plt++;
plt++;
}
}
U0 load_elf(...) {
if (argc < 1) {
PrintErr("Not enough arguments.\n");
return;
}
if (!FileFind(argv[0])) {
PrintErr("File not found: %s\n", argv[0]);
return;
}
Elf elf;
elf.u8 = FileRead(argv[0], &elf.size);
debug_print("Load file '%s', size = %d bytes\n", argv[0], elf.size);
if (!is_valid_elf(&elf)) {
PrintErr("File is not a valid ELF x86-64 executable.\n");
return;
}
process_elf_section_header_table(&elf);
process_elf_rela_dyn_entries(&elf);
process_elf_rela_plt_entries(&elf);
_start = elf.ehdr->e_entry;
elf_argc = argc;
elf_argv = argv;
_start();
}

@ -0,0 +1,32 @@
Bool @input_key_down(U8 scancode) { return Bt(kbd.down_bitmap, scancode); }
U0 _Z14input_key_downh() {
// input_key_down(unsigned char)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: input_key_down(%c)\n", p0);
@input_key_down(p0);
POP_SYSV_REGS
}
I64 @input_mouse_x() { return ms.pos.x; }
U0 _Z13input_mouse_xv() {
// input_mouse_x()
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: input_mouse_x()\n");
@input_mouse_x();
POP_SYSV_REGS
}
I64 @input_mouse_y() { return ms.pos.y; }
U0 _Z13input_mouse_yv() {
// input_mouse_y()
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: input_mouse_y()\n");
@input_mouse_y();
POP_SYSV_REGS
}

@ -0,0 +1,68 @@
#define stdin 0
#define stdout 1
#define stderr 2
U0 free() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: free(0x%08x)\n", p0);
Free(p0);
POP_SYSV_REGS
}
I64 @fwrite(U8 *ptr, I64 size, I64 nmemb, U64 stream) {
U8 *tmp;
switch (stream) {
case stdout:
case stderr:
tmp = CAlloc(size * nmemb);
MemCpy(tmp, ptr, nmemb - 1);
PutS(tmp);
Free(tmp);
"\n";
break;
default:
break;
}
return size * nmemb;
}
U0 fwrite() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fwrite(0x%08x, %d, %d, 0x%08x)\n", p0, p1, p2, p3);
@fwrite(p0, p1, p2, p3);
POP_SYSV_REGS
}
U0 malloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: malloc(%d)\n", p0);
MAlloc(p0);
POP_SYSV_REGS
}
U0 memcpy() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memcpy(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
MemCpy(p0, p1, p2);
POP_SYSV_REGS
}
U0 memset() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memset(0x%08x, %d, %d)\n", p0, p1, p2);
MemSet(p0, p1, p2);
POP_SYSV_REGS
}
U0 strlen() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strlen(\"%s\")\n", p0);
StrLen(p0);
POP_SYSV_REGS
}

@ -0,0 +1,818 @@
extern U64 get_symbol_address(U8 *entry_name);
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
U64 find_u32_in_memory(U64 offset, U32 value) {
I64 i = 0;
while (MemCmp(offset + i, &value, 4))
i++;
return offset + i;
}
U8 *f_whence[3];
f_whence[0] = "SEEK_SET";
f_whence[1] = "SEEK_CUR";
f_whence[2] = "SEEK_END";
class FILE {
U8 *filename;
U8 *data;
U8 *mode;
I64 descriptor;
I64 size;
I64 offset;
I64 pos;
};
class va_list {
U32 gp_offset;
U32 fp_offset;
U8 *overflow_arg_area;
U8 *reg_save_area;
};
FILE *iwad_fp = NULL;
#define PUSH_SYSV_REGS \
asm {PUSH RCX PUSH RDX PUSH RBX PUSH RBP PUSH RSI PUSH RDI PUSH R8 PUSH R9 PUSH \
R10 PUSH R11 PUSH R12 PUSH R13 PUSH R14 PUSH R15}
#define POP_SYSV_REGS \
asm {POP R15 POP R14 POP R13 POP R12 POP R11 POP R10 POP R9 POP R8 POP RDI POP \
RSI POP RBP POP RBX POP RDX POP RCX}
#define MOV_ANS_RAX asm {MOV [&ans], RAX}
#define MOV_P0_RDI asm {MOV [&p0], RDI}
#define MOV_P1_RSI asm {MOV [&p1], RSI}
#define MOV_P2_RDX asm {MOV [&p2], RDX}
#define MOV_P3_RCX asm {MOV [&p3], RCX}
#define MOV_P4_R8 asm {MOV [&p4], R8}
#define MOV_P5_R9 asm {MOV [&p5], R9}
#define GET_SYSV_ARGS \
MOV_P0_RDI MOV_P1_RSI MOV_P2_RDX MOV_P3_RCX MOV_P4_R8 MOV_P5_R9
I64 new_fd = 3;
I64 p0, p1, p2, p3, p4, p5;
I64 elf_argc;
U8 **elf_argv;
#define stdin 0
#define stdout 1
#define stderr 2
asm {
_ELF_CALL::
PUSH RBP
MOV RBP,RSP
MOV RAX,U64 SF_ARG1[RBP]
MOV RDI,U64 SF_ARG2[RBP]
MOV RSI,U64 SF_ARG3[RBP]
TEST RAX,RAX
JZ @@05
CALL RAX
@@05: POP RBP
RET1 8
}
U0 _main() {
MOV_P0_RDI
CallInd(_ELF_CALL, p0, elf_argc, elf_argv);
MOV_ANS_RAX
throw('end', TRUE);
}
U0 _exit() {
MOV_ANS_RAX
throw('end', TRUE);
}
U0 convert_format_string(U8 *s) {
while (*s) {
switch (*s) {
case '%':
if (s[1] == 'i')
s[1] = 'd';
if (s[1] == 'p')
s[1] = 'x';
break;
}
s++;
}
}
U0 putc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: putc('%c', %d)\n", p0, p1);
switch (p1) {
case stdout:
case stderr:
PutChars(p0);
break;
default:
PrintErr("putc: not yet implemented\n");
break;
}
POP_SYSV_REGS
}
U0 @assert_fail(U8 *assertion, U8 *file, U32 line, U8 *function) {
"%s:%d: %s: %s\n", file, line, function, assertion;
}
U0 __assert_fail() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
@assert_fail(p0, p1, p2, p3);
POP_SYSV_REGS
}
U64 @nothrow_t() { return CAlloc(1048576); }
U0 _ZnwmRKSt9nothrow_t() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
@nothrow_t;
POP_SYSV_REGS
}
I32 @ferror() { return -1; }
U0 ferror() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
@ferror;
POP_SYSV_REGS
}
U8 *@calloc(I64 nitems, I64 size) {
return CAlloc(nitems * size, Fs->code_heap);
}
U0 calloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: calloc(%d, %d)\n", p0, p1);
@calloc(p0, p1);
POP_SYSV_REGS
}
U8 *@getenv(U8 *str) {
if (!StrCmp(str, "HOME"))
return "B:";
return NULL;
}
U0 getenv() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: getenv(\"%s\")\n", p0);
@getenv(p0);
POP_SYSV_REGS
}
I64 @fileno(FILE *f) {
debug_print("fileno: 0x%08x has fd %d\n", f, f->descriptor);
return f->descriptor;
}
U0 fileno() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fileno(0x%08x)\n", p0);
@fileno(p0);
POP_SYSV_REGS
}
I64 @fflush(FILE *f) {
no_warn f;
return NULL;
}
U0 fflush() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fflush(0x%08x)\n", p0);
@fflush(p0);
POP_SYSV_REGS
}
I64 @fclose(FILE *f) {
if (!f)
return NULL;
if (f->data)
Free(f->data);
if (f->filename)
Free(f->filename);
if (f->mode)
Free(f->mode);
Free(f);
return NULL;
}
U0 fclose() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fclose(%d)\n", p0(FILE *)->descriptor);
@fclose(p0);
POP_SYSV_REGS
}
FILE *@fopen(U8 *filename, U8 *mode) {
U64 file_data;
FILE *f;
if (!StrCmp(mode, "r") || !StrCmp(mode, "r+") || !StrCmp(mode, "rb")) {
if (!FileFind(filename))
return NULL;
f = MAlloc(sizeof(FILE), Fs->code_heap);
f->filename = StrNew(filename);
file_data = FileRead(filename, &f->size);
f->data = CAlloc(f->size, Fs->code_heap);
// MemCpy(f->data, file_data, f->size);
MemCpy(f->data, file_data, f->size);
f->descriptor = new_fd++;
f->mode = StrNew(mode);
debug_print("fopen: got file descriptor %d\n", f->descriptor);
return f;
}
}
U0 fopen() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fopen(\"%s\",\"%s\")\n", p0, p1);
@fopen(p0, p1);
POP_SYSV_REGS
}
I64 @fread(U8 *ptr, I64 size, I64 nmemb, FILE *f) {
MemCpy(ptr, f->data + f->pos, (size * nmemb));
//"fread @ pos, size: %d, %d\n", f->pos, (size * nmemb);
// D(ptr, Min(256, size * nmemb));
f->pos += (size * nmemb);
// if (debug.enabled)
// debug_print("fread: pos: %d\n", f->pos);
return (size * nmemb);
}
U0 efread() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called fread(0x%08x, %d, %d, %d)\n", p0, p1, p2,
p3(FILE *)->descriptor);
@fread(p0, p1, p2, p3);
POP_SYSV_REGS
}
U0 free() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called free(0x%08x)\n", p0);
Free(p0);
POP_SYSV_REGS
}
I64 @fseek(FILE *f, I64 off, I64 whence) {
switch (whence) {
case SEEK_SET:
f->pos = off;
break;
case SEEK_CUR:
f->pos += off;
break;
case SEEK_END:
f->pos = f->size + off;
break;
}
return NULL;
}
U0 fseek() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fseek(%d, %d, %s)\n", p0(FILE *)->descriptor, p1,
f_whence[p2]);
@fseek(p0, p1, p2);
POP_SYSV_REGS
}
I64 @ftell(FILE *f) {
debug_print("ftell: %d\n", f->pos);
return f->pos;
}
U0 ftell() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: ftell(%d)\n", p0(FILE *)->descriptor);
@ftell(p0);
POP_SYSV_REGS
}
I64 @fwrite(U8 *ptr, I64 size, I64 nmemb, FILE *f) {
return (size * nmemb);
MemCpy(f->data + f->pos, ptr, (size * nmemb));
if (debug.enabled)
D(f->data + f->pos, Min(256, size * nmemb));
f->pos += (size * nmemb);
debug_print("fwrite: pos: %d\n", f->pos);
return (size * nmemb);
}
I64 @fwrite2(U8 *ptr, I64 size, I64 nmemb, FILE *f) {
no_warn f;
// debug_print("called: puts(%d)\n", ptr);
U8 *tmp1 = CAlloc(nmemb);
MemCpy(tmp1, ptr, nmemb - 1);
PutS(tmp1);
Free(tmp1);
"\n";
return (size * nmemb);
}
U0 fwrite() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called fwrite(0x%08x, %d, %d, 0x%08x)\n", p0, p1, p2,
p3(FILE *)->descriptor);
if (p3(FILE *)->descriptor(U64) < 0x100000000)
@fwrite(p0, p1, p2, p3);
if (p3(FILE *)->descriptor(U64) >= 0x100000000) {
// mock for stderr problem
@fwrite2(p0, p1, p2, p3);
}
POP_SYSV_REGS
}
U0 _ZdlPv() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called operator delete(void*) (%d, %d, %d, %d)\n", p0, p1, p2,
p3);
POP_SYSV_REGS
}
U0 strerror(){PUSH_SYSV_REGS GET_SYSV_ARGS
POP_SYSV_REGS}
Bool @isatty(I64 fd) {
no_warn fd;
return FALSE;
}
U0 isatty() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: isatty(%d)\n", p0);
@isatty(p0);
POP_SYSV_REGS
}
U64 @malloc(I64 size) {
U64 ptr = NULL;
ptr = MAlloc(p0, Fs->code_heap);
debug_print("malloc(%d), result: 0x%08x\n", size, ptr);
return ptr;
}
U0 malloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: malloc(%d)\n", p0);
@malloc(p0);
POP_SYSV_REGS
}
U0 memcpy() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memcpy(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
MemCpy(p0, p1, p2);
POP_SYSV_REGS
}
U0 memcmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memcmp(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
MemCmp(p0, p1, p2);
POP_SYSV_REGS
}
U0 memset() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memset(0x%08x, %d, %d)\n", p0, p1, p2);
// if (debug.counter > 1845140)
// PressAKey;
MemSet(p0, p1, p2);
POP_SYSV_REGS
}
I64 @mkdir(U8 *path) {
path = StrNew(path);
while (path[StrLen(path) - 1] == '/')
path[StrLen(path) - 1] = NULL;
CDoc *olddoc = Fs->put_doc;
CDoc *tmpdoc = DocNew;
Fs->put_doc = tmpdoc;
DirMk(path);
Fs->put_doc = olddoc;
DocDel(tmpdoc);
return 0;
}
U0 mkdir() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: mkdir(\"%s\")\n", p0);
@mkdir(p0);
POP_SYSV_REGS
}
I64 @open(U8 *path) {
iwad_fp = @fopen(path, "rb");
return iwad_fp->descriptor;
}
U0 open() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: open(\"%s\", %d, %d)\n", p0, p1, p2);
@open(p0);
POP_SYSV_REGS
}
U0 lseek() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: lseek(%d, %d, %d)\n", p0, p1, p2);
@fseek(iwad_fp, p1, p2);
POP_SYSV_REGS
}
U8 *@mmap(I64 fd) {
no_warn fd;
MemSetU32(
find_u32_in_memory(get_symbol_address("W_CacheLumpNum"), 0xcafef00d),
iwad_fp->data, 1);
return iwad_fp->data;
}
U0 mmap() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: mmap(0x%08x, %d, %d, %d, %d, %d)\n", p0, p1, p2, p3, p4,
p5);
@mmap(p4);
POP_SYSV_REGS
}
U0 read() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called read(%d, 0x%08x, %d)\n", p0, p1, p2);
@fread(p1, 1, p2, iwad_fp);
POP_SYSV_REGS
}
I64 @putchar(I64 ch) {
if (ch != 0x8)
PutChars(ch);
if (ch == 0x8)
Fs->put_doc->cur_col--;
return 0;
}
U0 putchar() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: putchar(%d)\n", p0);
@putchar(p0);
POP_SYSV_REGS
}
U0 puts() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: puts(%d)\n", p0);
PutS(p0);
"\n";
POP_SYSV_REGS
}
U8 *@realloc(U8 *ptr, I64 size) {
U8 *new;
if (!ptr) {
new = MAlloc(size, Fs->code_heap);
} else {
new = MAlloc(size, Fs->code_heap);
MemCpy(new, ptr, size);
Free(ptr);
}
return new;
}
U0 realloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called realloc(0x%08x, %d)\n", p0, p1);
@realloc(p0, p1);
POP_SYSV_REGS
}
U0 strcasecmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strcasecmp(\"%s\",\"%s\")\n", p0, p1);
StrICmp(p0, p1);
POP_SYSV_REGS
}
U0 strcmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strcmp(\"%s\",\"%s\")\n", p0, p1);
StrCmp(p0, p1);
POP_SYSV_REGS
}
U0 strlen() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strlen(\"%s\")\n", p0);
StrLen(p0);
POP_SYSV_REGS
}
I64 @strncmp(U8 *s1, U8 *s2, I64 n) {
while (n && *s1 && (*s1 == *s2)) {
++s1;
++s2;
--n;
}
if (n == 0) {
return 0;
} else {
return (*s1 - *s2);
}
}
U0 strncmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strncmp(\"%s\", \"%s\", %d)\n", p0, p1, p2);
@strncmp(p0, p1, p2);
POP_SYSV_REGS
}
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
U8 @strncasecmp_charmap[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff};
I64 @strncasecmp(U8 *s1, U8 *s2, I64 n) {
U64 u1 = 0, u2 = 0;
for (n == n; n != 0; --n) {
u1 = *s1++;
u2 = *s2++;
if (@strncasecmp_charmap[u1] != @strncasecmp_charmap[u2]) {
return @strncasecmp_charmap[u1] - @strncasecmp_charmap[u2];
}
if (u1 == '\0') {
return 0;
}
}
return 0;
}
U0 strncasecmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strncasecmp(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
debug_print("strncasecmp: return value is %d\n", @strncasecmp(p0, p1, p2));
@strncasecmp(p0, p1, p2);
POP_SYSV_REGS
}
U8 *@strncpy(U8 *destination, U8 *source, I64 num) {
// return if no memory is allocated to the destination
if (destination == NULL) {
return NULL;
}
// take a pointer pointing to the beginning of the destination string
U8 *ptr = destination;
// copy first `num` characters of C-string pointed by source
// into the array pointed by destination
while (*source && num--) {
*destination = *source;
destination++;
source++;
}
// null terminate destination string
*destination = '\0';
// the destination is returned by standard `strncpy()`
return ptr;
}
U0 strncpy() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strncpy(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
@strncpy(p0, p1, p2);
POP_SYSV_REGS
}
U8 *@strrchr(U8 *str, I64 ch) {
U8 str2[2];
str2[0] = ch;
str2[1] = NULL;
return StrLastOcc(str, &str2);
}
U0 strrchr() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called strrchr(\"%s\",'%c')\n", p0, p1);
@strrchr(p0, p1);
POP_SYSV_REGS
}
U8 *CTYPE_TOUPPER_LOC = MAlloc(256, Fs->code_heap);
;
I64 @ctype_toupper_i;
for (@ctype_toupper_i = 0; @ctype_toupper_i < 256; @ctype_toupper_i++) {
switch (@ctype_toupper_i) {
case 'a' ... 'z':
CTYPE_TOUPPER_LOC[@ctype_toupper_i] = @ctype_toupper_i - 0x20;
break;
default:
CTYPE_TOUPPER_LOC[@ctype_toupper_i] = @ctype_toupper_i;
break;
}
}
U8 *@__ctype_toupper_loc() { return &CTYPE_TOUPPER_LOC; }
U0 __ctype_toupper_loc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: __ctype_toupper_loc()\n");
@__ctype_toupper_loc;
POP_SYSV_REGS
}
U0 printf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: printf(\"%s\")\n", p0);
convert_format_string(p0);
Print(p0, p1, p2, p3, p4, p5);
POP_SYSV_REGS
}
U0 system() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: system(\"%s\")\n", p0);
POP_SYSV_REGS
}
U0 toupper() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: toupper(\"%c\")\n", p0);
ToUpper(p0);
POP_SYSV_REGS
}
I64 @tolower(I64 ch) {
switch (ch) {
case 'A' ... 'Z':
return ch + 0x20;
break;
default:
return ch;
}
}
U0 tolower() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: tolower(\"%c\")\n", p0);
@tolower(p0);
POP_SYSV_REGS
}
U0 time() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: time(%d)\n", p0);
SysTimerRead;
POP_SYSV_REGS
}
U0 vfprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: vfprintf(0x%08x, 0x%08x, 0x%08x)\n", p0, p1, p2);
switch (p0) {
case 1:
// PutS(p2);
va_list *ap = p2;
U64 va_ptr = ap->reg_save_area;
va_ptr += ap->gp_offset;
Print(p1, *va_ptr(U64 *));
debug_print("addr is : 0x%08x\n", *va_ptr(U64 *));
break;
}
POP_SYSV_REGS
}
U0 vprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: vprintf()\n");
va_list *ap = p1;
U64 va_ptr = ap->reg_save_area;
va_ptr += ap->gp_offset;
Print(p0, *va_ptr(U64 *));
debug_print("addr is : 0x%08x\n", *va_ptr(U64 *));
POP_SYSV_REGS
}
U0 snprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: snprintf()\n");
Print(p0, p2, p3, p4, p5);
POP_SYSV_REGS
}
U8 @strchr(U8 *s, I64 c) {
do {
if (*s == c) {
return s;
}
} while (*s++);
return 0;
}
U0 strchr() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: snprintf()\n");
@strchr(p0, p1);
POP_SYSV_REGS
}
U0 vsnprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: vsnprintf()\n");
va_list *ap = p3;
U64 va_ptr = ap->reg_save_area;
U64 va_ptr2;
U64 va_ptr3;
va_ptr += ap->gp_offset;
va_ptr2 = va_ptr + 8;
va_ptr3 = va_ptr2 + 8;
if (StrFind("STCFN", p2) || debug.counter > 1646600) {
//"string: %s\n", p2;
// PressAKey;
}
convert_format_string(p2);
StrPrint(p0, p2, *va_ptr(U64 *), *va_ptr2(U64 *), *va_ptr3(U64 *));
POP_SYSV_REGS
}

@ -0,0 +1,24 @@
U0 PatchCallRel32(U32 from, U32 to) {
*(from(U8 *)) = 0xE8;
*((from + 1)(I32 *)) = to - from - 5;
}
U0 PatchJmpRel32(U32 from, U32 to) {
*(from(U8 *)) = 0xE9;
*((from + 1)(I32 *)) = to - from - 5;
}
U0 EnableSSE() {
asm
{
MOV_EAX_CR0
AND AX, 0xFFFB // clear coprocessor emulation CR0.EM
OR AX, 0x2 // set coprocessor monitoring CR0.MP
MOV_CR0_EAX
MOV_EAX_CR4
OR AX, 3 << 9 // set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
MOV_CR4_EAX
}
}
EnableSSE;

@ -0,0 +1,17 @@
U0 _ZdlPv() {
// operator delete(void*)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: operator delete(0x%08x)\n", p0);
Free(p0);
POP_SYSV_REGS
}
U0 _ZnwmRKSt9nothrow_t() {
// operator new(unsigned long, std::nothrow_t const&)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: operator new(%d)\n", p0);
MAlloc(p0);
POP_SYSV_REGS
}

@ -0,0 +1,17 @@
U0 _Z7os_exitv() {
// os_exit()
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called os_exit()\n");
UserTaskCont;
POP_SYSV_REGS
}
U0 _Z14os_press_a_keyv() {
// os_press_a_key()
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called os_press_a_key()\n");
PressAKey;
POP_SYSV_REGS
}

@ -0,0 +1,8 @@
U0 _Z10time_sleepl() {
// time_sleep(long)
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: time_sleep(%d)\n", p0);
Sleep(p0);
POP_SYSV_REGS
}

@ -0,0 +1,21 @@
/* clang-format off */
#include "Lib/Debug";
#include "Lib/Misc";
#include "Lib/Base";
#include "Lib/LibC";
#include "Lib/New";
#include "Lib/OS";
#include "Lib/DC";
#include "Lib/Input";
#include "Lib/Time";
#include "Lib/ELF64";
/* clang-format on */
IsRaw; // Quick and dirty method to return 0
load_elf("build/program");

@ -0,0 +1 @@
XTalkWait(Fs, "#include \"Load\";\n");

@ -0,0 +1,72 @@
import extern c "/home/alec/repos/unholy-jakt/include/dc.h" {}
class DC {
public width: i64
public height: i64
context: usize
public function blot(this, dc: DC, x: i64, y: i64) {
unsafe {
cpp {
"dc_blot(dc->context, x, y, this->context);"
}
}
}
public function copy(this, dc: DC, x: i64, y: i64) {
unsafe {
cpp {
"dc_copy(dc->context, x, y, this->context);"
}
}
}
public function create_rect(width: i64, height: i64) throws -> DC {
mut dc = DC(width: width, height: height, context: 0);
dc.init()
return dc
}
public function fill(this, color: i64) {
unsafe {
cpp {
"dc_fill(this->context, color);"
}
}
}
public function gr_dc_alias() throws -> DC {
mut dc = DC(width: 0, height: 0, context: 0);
unsafe {
cpp {
"dc->context = dc_gr_dc_alias(&dc->width, &dc->height);"
}
}
return dc
}
public function init(mut this) {
unsafe {
cpp {
"this->context = dc_new(this->width, this->height);"
}
}
}
public function integer_scale(mut this, scale_factor: i64) {
unsafe {
cpp {
"this->context = dc_integer_scale(this->context, scale_factor, &this->width, &this->height);"
}
}
}
public function load_from_file(filename: String) throws -> DC {
mut dc = DC(width: 0, height: 0, context: 0);
unsafe {
cpp {
"dc->context = dc_load_from_file(filename.c_string(), &dc->width, &dc->height);"
}
}
return dc
}
public function replace_color(this, from: i64, to: i64) {
unsafe {
cpp {
"dc_replace_color(this->context, from, to);"
}
}
}
}

@ -0,0 +1,8 @@
void dc_blot(unsigned long dest, unsigned long x, unsigned long y, unsigned long src);
void dc_copy(unsigned long dest, unsigned long x, unsigned long y, unsigned long src);
void dc_fill(unsigned long context, unsigned long color);
unsigned long dc_gr_dc_alias(long *width, long *height);
unsigned long dc_integer_scale(unsigned long context, long scale_factor, long *width, long *height);
unsigned long dc_load_from_file(const char * filename, long *width, long *height);
unsigned long dc_new(unsigned long width, unsigned long height);
unsigned long dc_replace_color(unsigned long context, unsigned long from, unsigned long to);

@ -0,0 +1,3 @@
bool input_key_down(u8 scancode);
i64 input_mouse_x();
i64 input_mouse_y();

@ -0,0 +1,2 @@
void os_press_a_key();
void os_exit();

@ -0,0 +1 @@
void time_sleep(i64 duration);

@ -0,0 +1,31 @@
import extern c "/home/alec/repos/unholy-jakt/include/input.h" {}
struct Input {
function key_down(scancode: u8) -> bool {
mut key_is_down = false;
unsafe {
cpp {
"key_is_down = input_key_down(scancode);";
}
}
return key_is_down;
}
function mouse_x() -> i64 {
mut x = 0
unsafe {
cpp {
"x = input_mouse_x();";
}
}
return x;
}
function mouse_y() -> i64 {
mut y = 0
unsafe {
cpp {
"y = input_mouse_y();";
}
}
return y;
}
}

@ -0,0 +1,27 @@
void dc_blot(unsigned long dest, unsigned long x, unsigned long y, unsigned long src) {}
void dc_copy(unsigned long dest, unsigned long x, unsigned long y, unsigned long src) {}
void dc_fill(unsigned long context, unsigned long color) {}
unsigned long dc_gr_dc_alias(long *width, long *height) { return 0; }