├── Decompiled ├── GameState.d ├── GameplayFrontEnd.d ├── GameplayInside.d ├── GameplayOutside.d ├── Level.d ├── Level1Greece.d ├── Level2America.d ├── Level2Java.d ├── Level4Siberia.d ├── Level5Comet.d ├── N64.d ├── Os.d ├── Program.d ├── RAM.d ├── bh_dis_Greece_U_GameplayInside.txt ├── bh_dis_Greece_U_Gameplayoutside.txt ├── bh_dis_Greece_U_Level.txt ├── bh_dis_Greece_U_N64.txt └── bh_dis_U_StartMenu.txt ├── Dockerfile ├── Makefile ├── Makefile.split ├── README.md ├── body_harvest.u.ld ├── body_harvest.u.s ├── body_harvest.u.yaml ├── geo_commands.inc ├── globals.inc ├── include ├── PR │ ├── abi.h │ ├── gbi.h │ ├── gbi.inc │ ├── gbi_old.h │ ├── gs2dex.h │ ├── gu.h │ ├── libaudio.h │ ├── libultra.h │ ├── mbi.h │ ├── os_ai.h │ ├── os_cache.h │ ├── os_cont.h │ ├── os_eeprom.h │ ├── os_exception.h │ ├── os_internal.h │ ├── os_libc.h │ ├── os_message.h │ ├── os_misc.h │ ├── os_pi.h │ ├── os_rdp.h │ ├── os_thread.h │ ├── os_time.h │ ├── os_tlb.h │ ├── os_vi.h │ ├── sptask.h │ ├── ucode.h │ └── ultratypes.h ├── math.h └── ultra64.h ├── macros.inc ├── src └── base │ ├── EF98.c │ ├── EF98.h │ ├── F618.c │ └── F618.h ├── tools ├── .gitignore ├── Makefile ├── asm_processor │ ├── asm-processor.py │ ├── build.py │ └── prelude.inc ├── calc_bss.sh ├── hashtable.c ├── hashtable.h ├── ido5.3_compiler │ ├── lib │ │ ├── libmalloc.so │ │ ├── libmalloc_old.so │ │ └── rld │ └── usr │ │ ├── bin │ │ └── cc │ │ └── lib │ │ ├── as0 │ │ ├── as1 │ │ ├── cfe │ │ ├── crt1.o │ │ ├── err.english.cc │ │ ├── libc.so.1 │ │ ├── libexc.so │ │ ├── libgen.so │ │ ├── libm.so │ │ ├── ugen │ │ ├── ujoin │ │ ├── uld │ │ ├── umerge │ │ ├── uopt │ │ └── usplit ├── iplfontutil.c ├── libmio0.c ├── libmio0.h ├── libsm64.c ├── libsm64.h ├── n64cksum.c ├── n64graphics.c ├── n64graphics.h ├── n64graphics_ci_dir │ ├── LICENSE │ ├── README.md │ ├── exoquant │ │ ├── exoquant.c │ │ └── exoquant.h │ ├── n64graphics_ci.c │ ├── n64graphics_ci.h │ ├── utils.c │ └── utils.h ├── patch_libultra_math.c ├── sm64tools.LICENSE ├── stb │ ├── stb_image.h │ └── stb_image_write.h ├── textconv.c ├── utf8.c ├── utf8.h ├── utils.c └── utils.h └── undefined_syms.txt /Decompiled/GameState.d: -------------------------------------------------------------------------------- 1 | module gameState; 2 | 3 | interface IGameState 4 | { 5 | int Start(int a0); 6 | } -------------------------------------------------------------------------------- /Decompiled/Level.d: -------------------------------------------------------------------------------- 1 | module level; 2 | 3 | interface ILevel 4 | { 5 | int Start(int a0, int a1); 6 | } -------------------------------------------------------------------------------- /Decompiled/Level2America.d: -------------------------------------------------------------------------------- 1 | module america; 2 | 3 | import n64, gameplayOutside; 4 | 5 | class America 6 | { 7 | public: 8 | // RAM AMERICA 9 | void Start() { 10 | fnc000efeb4(); 11 | fnc000efeb4(); 12 | fnc000efeb4(); 13 | fnc002d5110(); 14 | fnc002d4e70(); 15 | fnc00007690(); 16 | } 17 | 18 | // RAM AMERICA 19 | void fnc002d4dd4() { 20 | fnc000fb468(); 21 | fnc000fb468(); 22 | fnc000fb468(); 23 | fnc0000726c(); 24 | Start(); 25 | } 26 | 27 | // RAM AMERICA 28 | void fnc002d4e70() { 29 | fnc0000726c(); 30 | fnc000076d4(); 31 | fnc00004818(); 32 | fnc000076d4(); 33 | fnc00004818(); 34 | fnc000076d4(); 35 | fnc00004818(); 36 | fnc000076d4(); 37 | fnc00004818(); 38 | fnc000076d4(); 39 | fnc00004818(); 40 | fnc000076d4(); 41 | fnc00004818(); 42 | fnc000076d4(); 43 | } 44 | 45 | // RAM AMERICA 46 | void fnc002d4fbc() { 47 | fnc000076d4(); 48 | fnc00013468(); 49 | fnc000efeb4(); 50 | fnc000072cc(); 51 | fnc002d5190(); 52 | fnc000074bc(); 53 | } 54 | 55 | // RAM AMERICA 56 | void fnc002d5044() { 57 | fnc000072cc(); 58 | fnc000072cc(); 59 | fnc000074bc(); 60 | fnc0001cc6c(); 61 | fnc000072cc(); 62 | fnc000074bc(); 63 | fnc0001cc6c(); 64 | } 65 | 66 | // RAM AMERICA 67 | void fnc002d5110() { 68 | fnc00007410(); 69 | fnc00007410(); 70 | } 71 | 72 | // RAM AMERICA 73 | void fnc002d5148() { 74 | fnc000073b8(); 75 | } 76 | 77 | // RAM AMERICA 78 | void fnc002d516c() { 79 | fnc000073b8(); 80 | } 81 | 82 | // RAM AMERICA 83 | void fnc002d5190() { 84 | } 85 | 86 | // RAM AMERICA 87 | void fnc002d51b8() { 88 | fnc0000726c(); 89 | fnc000df038(); 90 | } 91 | 92 | // RAM AMERICA 93 | void fnc002d5288() { 94 | fnc000072cc(); 95 | } 96 | 97 | // RAM AMERICA 98 | void fnc002d52b0() { 99 | fnc0007956c(); 100 | fnc0011e6fc(); 101 | fnc000ae454(); 102 | } 103 | 104 | // RAM AMERICA 105 | void fnc002d536c() { 106 | fnc0009bf64(); 107 | fnc000074bc(); 108 | } 109 | 110 | // RAM AMERICA 111 | void fnc002d53bc() { 112 | fnc0007956c(); 113 | } 114 | 115 | // RAM AMERICA 116 | void fnc002d5440() { 117 | fnc002d53bc(); 118 | fnc00007410(); 119 | } 120 | 121 | // RAM AMERICA 122 | void fnc002d546c() { 123 | fnc000074bc(); 124 | fnc00087aac(); 125 | } 126 | 127 | // RAM AMERICA 128 | void fnc002d5530() { 129 | fnc000076d4(); 130 | openCurrentStageGate(); 131 | fnc000074bc(); 132 | fnc00087aac(); 133 | } 134 | 135 | // RAM AMERICA 136 | void fnc002d55a0() { 137 | fnc0001cc6c(); 138 | } 139 | 140 | // RAM AMERICA 141 | void fnc002d55e4() { 142 | } 143 | 144 | // RAM AMERICA 145 | void fnc002d563c() { 146 | fnc00013468(); 147 | fnc000072cc(); 148 | fnc000b84d0(); 149 | fnc000df038(); 150 | fnc000b84d0(); 151 | fnc000df038(); 152 | fnc0007956c(); 153 | fnc0007a198(); 154 | fnc000dee5c(); 155 | fnc000dee5c(); 156 | fnc000d05a8(); 157 | guess_destroyAlien(); 158 | } 159 | 160 | // RAM AMERICA 161 | void fnc002d5ca8() { 162 | fnc00137468(); 163 | fnc0008064c(); 164 | } 165 | 166 | // RAM AMERICA 167 | void fnc002d5d08() { 168 | fnc00137468(); 169 | fnc0008064c(); 170 | fnc0008076c(); 171 | fnc000a53c0(); 172 | fnc00084e54(); 173 | fnc00084fe8(); 174 | fnc000868a4(); 175 | fnc0011e6fc(); 176 | fnc00129354(); 177 | fnc00088760(); 178 | fnc0008e978(); 179 | fnc0008edfc(); 180 | fnc00092c40(); 181 | fnc0008e524(); 182 | fnc0008eb20(); 183 | fnc0008eb20(); 184 | } 185 | 186 | // RAM AMERICA 187 | void fnc002d5f88() { 188 | coss(); 189 | fnc0001d980(); 190 | fnc00088e40(); 191 | fnc000df848(); 192 | } 193 | 194 | // RAM AMERICA 195 | void fnc002d6138() { 196 | fnc000df848(); 197 | fnc00124b5c(); 198 | fnc002d5f88(); 199 | fnc0008aafc(); 200 | } 201 | 202 | // RAM AMERICA 203 | void fnc002d62a0() { 204 | coss(); 205 | fnc0001d980(); 206 | fnc0001d980(); 207 | coss(); 208 | fnc00128428(); 209 | fnc00128428(); 210 | fnc000d16bc(); 211 | fnc00087188(); 212 | fnc00081c84(); 213 | fnc00081e5c(); 214 | } 215 | 216 | // RAM AMERICA 217 | void fnc002d65bc() { 218 | fnc00091470(); 219 | fnc0009170c(); 220 | } 221 | 222 | // RAM AMERICA 223 | void fnc002d6684() { 224 | fnc0008e478(); 225 | fnc002d65bc(); 226 | fnc002d62a0(); 227 | fnc000850dc(); 228 | fnc0008e524(); 229 | fnc000a5554(); 230 | } 231 | 232 | // RAM AMERICA 233 | void fnc002d6824() { 234 | fnc00137468(); 235 | fnc0008076c(); 236 | } 237 | 238 | // RAM AMERICA 239 | void fnc002d6890() { 240 | fnc00089200(); 241 | fnc00085780(); 242 | fnc000859f4(); 243 | fnc00085e2c(); 244 | fnc000808f0(); 245 | fnc0008554c(); 246 | fnc00084fe8(); 247 | fnc00128428(); 248 | fnc000c56a4(); 249 | fnc00128428(); 250 | fnc000c56a4(); 251 | fnc000870d8(); 252 | fnc00086d70(); 253 | fnc00087188(); 254 | fnc00137468(); 255 | fnc00081f18(); 256 | fnc00081f18(); 257 | fnc0001d980(); 258 | coss(); 259 | coss(); 260 | fnc0001d980(); 261 | fnc0001d980(); 262 | coss(); 263 | fnc000879a4(); 264 | fnc00102ddc(); 265 | fnc00137468(); 266 | fnc0001d980(); 267 | coss(); 268 | fnc000c541c(); 269 | fnc00137468(); 270 | fnc00122524(); 271 | } 272 | 273 | // RAM AMERICA 274 | void fnc002d736c() { 275 | fnc00089eb4(); 276 | fnc000893c8(); 277 | fnc000893c8(); 278 | fnc000893c8(); 279 | fnc000893c8(); 280 | fnc000893c8(); 281 | fnc000b84d0(); 282 | fnc000df848(); 283 | fnc00088e40(); 284 | fnc0001d980(); 285 | coss(); 286 | fnc00088e40(); 287 | fnc0001d980(); 288 | coss(); 289 | fnc00088e40(); 290 | } 291 | 292 | // RAM AMERICA 293 | void fnc002d7840() { 294 | fnc00081f18(); 295 | fnc00084fe8(); 296 | fnc000871cc(); 297 | fnc00087188(); 298 | fnc00137468(); 299 | } 300 | 301 | // RAM AMERICA 302 | void fnc002d7968() { 303 | fnc00081f18(); 304 | fnc00081f18(); 305 | fnc000879a4(); 306 | fnc00137468(); 307 | fnc0001d980(); 308 | coss(); 309 | fnc000c541c(); 310 | fnc00122524(); 311 | fnc00102ddc(); 312 | fnc00137468(); 313 | fnc00137468(); 314 | } 315 | 316 | // RAM AMERICA 317 | void fnc002d7c00() { 318 | fnc00081f18(); 319 | fnc00137468(); 320 | } 321 | 322 | // RAM AMERICA 323 | void fnc002d7d08() { 324 | fnc00081f18(); 325 | fnc00128428(); 326 | fnc00128428(); 327 | fnc000b84d0(); 328 | fnc000dee5c(); 329 | fnc00135d44(); 330 | fnc001371b8(); 331 | fnc000dea08(); 332 | fnc000c541c(); 333 | fnc00124b5c(); 334 | fnc00102ddc(); 335 | } 336 | 337 | // RAM AMERICA 338 | void fnc002d803c() { 339 | fnc00137468(); 340 | fnc00090a6c(); 341 | fnc00090a6c(); 342 | fnc00090a6c(); 343 | fnc00090a6c(); 344 | fnc00090a6c(); 345 | fnc00090a6c(); 346 | fnc00086230(); 347 | fnc000877e8(); 348 | fnc000038e0(); 349 | fnc00137468(); 350 | fnc00084fe8(); 351 | fnc002d7968(); 352 | fnc002d7968(); 353 | fnc002d7840(); 354 | fnc002d7c00(); 355 | } 356 | 357 | // RAM AMERICA 358 | void fnc002d83d0() { 359 | fnc000877e8(); 360 | fnc00090a6c(); 361 | fnc00090a6c(); 362 | fnc00090a6c(); 363 | fnc00090a6c(); 364 | fnc00086230(); 365 | fnc000038e0(); 366 | fnc00137468(); 367 | fnc00084e54(); 368 | fnc00084fe8(); 369 | fnc000038e0(); 370 | fnc00084fe8(); 371 | fnc00087188(); 372 | fnc002d7d08(); 373 | fnc002d7840(); 374 | fnc00128504(); 375 | fnc000d05a8(); 376 | fnc00137468(); 377 | fnc000a3d00(); 378 | } 379 | 380 | // RAM AMERICA 381 | void fnc002d86d8() { 382 | fnc00137468(); 383 | fnc000df848(); 384 | fnc0008741c(); 385 | fnc00081f18(); 386 | fnc0001d980(); 387 | coss(); 388 | fnc00088e40(); 389 | fnc0001d980(); 390 | coss(); 391 | fnc00088e40(); 392 | fnc0001d980(); 393 | coss(); 394 | fnc00088e40(); 395 | fnc0001d980(); 396 | coss(); 397 | fnc00088e40(); 398 | fnc00128428(); 399 | fnc000b84d0(); 400 | fnc000865f4(); 401 | fnc0001d980(); 402 | coss(); 403 | fnc00088e40(); 404 | fnc00137468(); 405 | fnc00128428(); 406 | fnc0001d980(); 407 | coss(); 408 | fnc000038e0(); 409 | fnc000ca5ec(); 410 | fnc000df848(); 411 | } 412 | 413 | // RAM AMERICA 414 | void fnc002d9038() { 415 | fnc00087c50(); 416 | fnc00137468(); 417 | fnc00087c74(); 418 | fnc000893c8(); 419 | fnc00137468(); 420 | fnc00084e54(); 421 | fnc002d7d08(); 422 | fnc0001d980(); 423 | coss(); 424 | fnc00088e40(); 425 | fnc0001d980(); 426 | coss(); 427 | fnc00088e40(); 428 | fnc00128504(); 429 | fnc000d05a8(); 430 | fnc000038e0(); 431 | fnc000b84d0(); 432 | fnc000038e0(); 433 | fnc000865f4(); 434 | fnc000df848(); 435 | } 436 | 437 | // RAM AMERICA 438 | void fnc002d9510() { 439 | fnc00084fe8(); 440 | fnc000038e0(); 441 | fnc00084fe8(); 442 | fnc00081f18(); 443 | fnc00087188(); 444 | fnc00087188(); 445 | fnc00086164(); 446 | fnc0008e524(); 447 | fnc000a5554(); 448 | } 449 | 450 | // RAM AMERICA 451 | void fnc002d998c() { 452 | fnc00137468(); 453 | fnc0008735c(); 454 | } 455 | 456 | // RAM AMERICA 457 | void fnc002d99e4() { 458 | fnc000b84d0(); 459 | fnc0001d980(); 460 | fnc00084e54(); 461 | fnc0008064c(); 462 | fnc0008076c(); 463 | fnc0001d980(); 464 | coss(); 465 | fnc000dea08(); 466 | fnc00135d44(); 467 | fnc000c541c(); 468 | fnc00137468(); 469 | } 470 | 471 | // RAM AMERICA 472 | void fnc002d9f10() { 473 | fnc00081f18(); 474 | fnc00084fe8(); 475 | fnc000871cc(); 476 | fnc00087188(); 477 | fnc00137468(); 478 | } 479 | 480 | // RAM AMERICA 481 | void fnc002da054() { 482 | fnc00081f18(); 483 | } 484 | 485 | // RAM AMERICA 486 | void fnc002da120() { 487 | fnc000b84d0(); 488 | fnc00137468(); 489 | fnc00028100(); 490 | fnc000b84d0(); 491 | fnc000038e0(); 492 | fnc000038e0(); 493 | fnc000038e0(); 494 | fnc000dea08(); 495 | fnc00135d44(); 496 | fnc000038e0(); 497 | fnc000038e0(); 498 | fnc000dea08(); 499 | fnc00135d44(); 500 | fnc0001d980(); 501 | coss(); 502 | fnc000c541c(); 503 | } 504 | 505 | // RAM AMERICA 506 | void fnc002da520() { 507 | fnc000b84d0(); 508 | fnc00084e54(); 509 | fnc00080a54(); 510 | fnc002d9f10(); 511 | fnc002da054(); 512 | fnc00003824(); 513 | fnc00003824(); 514 | fnc00003824(); 515 | fnc00003824(); 516 | fnc00102ddc(); 517 | fnc002da120(); 518 | } 519 | 520 | // RAM AMERICA 521 | void fnc002da878() { 522 | fnc00079dc0(); 523 | fnc00079dc0(); 524 | fnc00079c8c(); 525 | fnc00079dc0(); 526 | fnc00079c8c(); 527 | fnc002d99e4(); 528 | fnc002da520(); 529 | } 530 | 531 | // RAM AMERICA 532 | void fnc002daa98() { 533 | } 534 | 535 | // RAM AMERICA 536 | void fnc002daaf0() { 537 | fnc00081f18(); 538 | fnc002da054(); 539 | fnc000b84d0(); 540 | fnc000ca5ec(); 541 | fnc0001d980(); 542 | coss(); 543 | fnc000a931c(); 544 | fnc000a931c(); 545 | fnc000a931c(); 546 | fnc00128428(); 547 | fnc000ca5ec(); 548 | fnc002da120(); 549 | } 550 | 551 | // RAM AMERICA 552 | void fnc002daedc() { 553 | fnc00128428(); 554 | fnc000038e0(); 555 | fnc000038e0(); 556 | fnc000038e0(); 557 | fnc000d16bc(); 558 | fnc0001d980(); 559 | fnc000dea08(); 560 | fnc00137468(); 561 | fnc000b84d0(); 562 | fnc000dea08(); 563 | fnc000b84d0(); 564 | fnc000c541c(); 565 | fnc00135d44(); 566 | fnc0001d980(); 567 | fnc0001d980(); 568 | coss(); 569 | fnc000d16bc(); 570 | fnc000b99a8(); 571 | fnc00137468(); 572 | fnc00084e54(); 573 | fnc000870d8(); 574 | fnc00086d70(); 575 | fnc000870d8(); 576 | fnc00086d70(); 577 | fnc000870d8(); 578 | fnc00086d70(); 579 | fnc000870d8(); 580 | fnc00086d70(); 581 | } 582 | 583 | // RAM AMERICA 584 | void fnc002db644() { 585 | fnc000800dc(); 586 | } 587 | 588 | // RAM AMERICA 589 | void fnc002db6b0() { 590 | fnc000df848(); 591 | fnc00088e10(); 592 | fnc000df848(); 593 | } 594 | 595 | // RAM AMERICA 596 | void fnc002db7b8() { 597 | fnc00137468(); 598 | coss(); 599 | coss(); 600 | fnc0001d980(); 601 | coss(); 602 | fnc0001d980(); 603 | coss(); 604 | fnc001022f4(); 605 | fnc001022f4(); 606 | fnc000b84d0(); 607 | } 608 | 609 | // RAM AMERICA 610 | void fnc002dbd08() { 611 | } 612 | 613 | // RAM AMERICA 614 | void fnc002dbd84() { 615 | fnc00014a3c(); 616 | fnc0001d980(); 617 | fnc0001d980(); 618 | fnc000dee5c(); 619 | fnc000dee5c(); 620 | fnc000dee5c(); 621 | fnc000c56a4(); 622 | fnc00137468(); 623 | fnc00011f90(); 624 | fnc00004214(); 625 | fnc00011f90(); 626 | fnc00004214(); 627 | } 628 | 629 | // RAM AMERICA 630 | void fnc002dc244() { 631 | fnc000b84d0(); 632 | fnc0008064c(); 633 | fnc00137468(); 634 | fnc00135d44(); 635 | fnc00137468(); 636 | fnc000dea08(); 637 | fnc000c541c(); 638 | fnc000e35e0(); 639 | fnc00084e54(); 640 | fnc00123ac4(); 641 | fnc00003824(); 642 | fnc00102ddc(); 643 | fnc000038e0(); 644 | fnc000038e0(); 645 | fnc000038e0(); 646 | fnc0001d980(); 647 | coss(); 648 | fnc000dfa34(); 649 | fnc00124b5c(); 650 | } 651 | 652 | // RAM AMERICA 653 | void fnc002dc7fc() { 654 | fnc00011f90(); 655 | fnc000039d0(); 656 | } 657 | 658 | // RAM AMERICA 659 | void fnc002dc880() { 660 | fnc00137468(); 661 | fnc00137468(); 662 | fnc000b84d0(); 663 | fnc000b2354(); 664 | fnc000a92e0(); 665 | fnc000a99b8(); 666 | fnc00086230(); 667 | fnc0001d940(); 668 | fnc00084fe8(); 669 | fnc002db7b8(); 670 | fnc00084fe8(); 671 | fnc002db7b8(); 672 | fnc002dbd84(); 673 | fnc002dc7fc(); 674 | fnc002dbd08(); 675 | fnc002dc244(); 676 | fnc000a9f34(); 677 | } 678 | 679 | // RAM AMERICA 680 | void fnc002dccd8() { 681 | fnc000a931c(); 682 | fnc000a931c(); 683 | fnc000a931c(); 684 | fnc000879a4(); 685 | fnc000a931c(); 686 | fnc000a931c(); 687 | fnc000a931c(); 688 | fnc000879a4(); 689 | fnc000a931c(); 690 | fnc000a931c(); 691 | fnc000a931c(); 692 | fnc000879a4(); 693 | } 694 | 695 | // RAM AMERICA 696 | void fnc002dd104() { 697 | fnc002dbd08(); 698 | fnc000860cc(); 699 | fnc00085a9c(); 700 | fnc00085f68(); 701 | fnc000a931c(); 702 | fnc000a931c(); 703 | fnc00128428(); 704 | fnc000a931c(); 705 | fnc000a931c(); 706 | fnc00128428(); 707 | fnc000d16bc(); 708 | fnc00081f18(); 709 | fnc00081f18(); 710 | fnc002dccd8(); 711 | fnc00102ddc(); 712 | fnc00137468(); 713 | fnc000851c8(); 714 | fnc000851c8(); 715 | fnc000a931c(); 716 | fnc000a931c(); 717 | fnc00128428(); 718 | fnc00135d44(); 719 | fnc000868a4(); 720 | fnc000038e0(); 721 | fnc000038e0(); 722 | } 723 | 724 | // RAM AMERICA 725 | void fnc002dd9c8() { 726 | fnc000a93a4(); 727 | fnc002dd104(); 728 | } 729 | 730 | // RAM AMERICA 731 | void fnc002dda64() { 732 | fnc000a93a4(); 733 | } 734 | 735 | // RAM AMERICA 736 | void fnc002dda98() { 737 | fnc000a93a4(); 738 | fnc002dd104(); 739 | } 740 | 741 | // RAM AMERICA 742 | void fnc002ddb34() { 743 | fnc000a93a4(); 744 | } 745 | 746 | // RAM AMERICA 747 | void fnc002ddb68() { 748 | fnc000a931c(); 749 | fnc00128428(); 750 | fnc0007956c(); 751 | guess_addActiveObject(); 752 | } 753 | 754 | // RAM AMERICA 755 | void fnc002ddc88() { 756 | fnc000a93a4(); 757 | fnc00081f18(); 758 | fnc002ddb68(); 759 | fnc00084fe8(); 760 | fnc00137468(); 761 | fnc00137468(); 762 | fnc00011f90(); 763 | fnc00004214(); 764 | } 765 | 766 | // RAM AMERICA 767 | void fnc002ddf04() { 768 | fnc000a93a4(); 769 | } 770 | 771 | // RAM AMERICA 772 | void fnc002ddf50() { 773 | fnc00137468(); 774 | fnc000b84d0(); 775 | fnc0001d980(); 776 | coss(); 777 | fnc000038e0(); 778 | fnc000c541c(); 779 | fnc000038e0(); 780 | fnc000038e0(); 781 | fnc0001d940(); 782 | fnc0008076c(); 783 | fnc000038e0(); 784 | fnc000038e0(); 785 | fnc00084e54(); 786 | fnc0008076c(); 787 | fnc000879a4(); 788 | coss(); 789 | fnc0001d980(); 790 | fnc000c541c(); 791 | fnc000dfa34(); 792 | coss(); 793 | fnc0001d980(); 794 | fnc00122524(); 795 | fnc00137468(); 796 | } 797 | 798 | // RAM AMERICA 799 | void fnc002de5e8() { 800 | fnc00088000(); 801 | fnc0012b21c(); 802 | fnc000a92b0(); 803 | fnc000df848(); 804 | fnc00137468(); 805 | fnc002db7b8(); 806 | fnc00128428(); 807 | fnc000df848(); 808 | fnc00088e10(); 809 | fnc00128428(); 810 | fnc000df848(); 811 | fnc00088e10(); 812 | fnc00135d44(); 813 | fnc00137468(); 814 | fnc000dea08(); 815 | fnc000c541c(); 816 | fnc000e35e0(); 817 | fnc00088000(); 818 | fnc000aa340(); 819 | fnc00137468(); 820 | } 821 | 822 | // RAM AMERICA 823 | void fnc002de990() { 824 | fnc00128428(); 825 | fnc000df848(); 826 | fnc000a931c(); 827 | fnc000a931c(); 828 | fnc00128428(); 829 | fnc000df848(); 830 | fnc000df848(); 831 | fnc00137468(); 832 | fnc000df848(); 833 | } 834 | 835 | // RAM AMERICA 836 | void fnc002dec0c() { 837 | fnc000a93a4(); 838 | fnc002de990(); 839 | } 840 | 841 | // RAM AMERICA 842 | void fnc002decac() { 843 | fnc000a93a4(); 844 | fnc002de990(); 845 | } 846 | 847 | // RAM AMERICA 848 | void fnc002ded4c() { 849 | fnc000a93a4(); 850 | fnc00089eb4(); 851 | } 852 | 853 | // RAM AMERICA 854 | void fnc002dee40() { 855 | fnc000df848(); 856 | } 857 | 858 | // RAM AMERICA 859 | void fnc002deed4() { 860 | fnc00135d44(); 861 | fnc001371b8(); 862 | fnc00135d44(); 863 | fnc001371b8(); 864 | fnc001371b8(); 865 | fnc001371b8(); 866 | fnc000039d0(); 867 | fnc000039d0(); 868 | fnc0012d700(); 869 | fnc0012d700(); 870 | } 871 | } 872 | -------------------------------------------------------------------------------- /Decompiled/Os.d: -------------------------------------------------------------------------------- 1 | module os; 2 | 3 | class OS 4 | { 5 | public: 6 | 7 | enum Priority 8 | { 9 | OS_PRIORITY_IDLE = 0, 10 | OS_PRIORITY_APPMAX = 127, 11 | OS_PRIORITY_SIMGR = 140, 12 | OS_PRIORITY_PIMGR = 150, 13 | OS_PRIORITY_RMONSPIN = 200, 14 | OS_PRIORITY_RMON = 250, 15 | OS_PRIORITY_VIMGR = 254, 16 | OS_PRIORITY_MAX = 255 17 | } 18 | 19 | enum ViSpecialFeature 20 | { 21 | OS_VI_GAMMA_ON = 0x0001, 22 | OS_VI_GAMMA_OFF = 0x0002, 23 | OS_VI_GAMMA_DITHER_ON = 0x0004, 24 | OS_VI_GAMMA_DITHER_OFF = 0x0008, 25 | OS_VI_DIVOT_ON = 0x0010, 26 | OS_VI_DIVOT_OFF = 0x0020, 27 | OS_VI_DITHER_FILTER_ON = 0x0040, 28 | OS_VI_DITHER_FILTER_OFF = 0x0080 29 | } 30 | 31 | enum ViMode 32 | { 33 | osViModeNtscLpn1, // Individual VI NTSC modes 34 | osViModeNtscLpf1, 35 | osViModeNtscLan1, 36 | osViModeNtscLaf1, 37 | osViModeNtscLpn2, 38 | osViModeNtscLpf2, 39 | osViModeNtscLan2, 40 | osViModeNtscLaf2, 41 | osViModeNtscHpn1, 42 | osViModeNtscHpf1, 43 | osViModeNtscHan1, 44 | osViModeNtscHaf1, 45 | osViModeNtscHpn2, 46 | osViModeNtscHpf2, 47 | osViModePalLpn1, // Individual VI PAL modes 48 | osViModePalLpf1, 49 | osViModePalLan1, 50 | osViModePalLaf1, 51 | osViModePalLpn2, 52 | osViModePalLpf2, 53 | osViModePalLan2, 54 | osViModePalLaf2, 55 | osViModePalHpn1, 56 | osViModePalHpf1, 57 | osViModePalHan1, 58 | osViModePalHaf1, 59 | osViModePalHpn2, 60 | osViModePalHpf2, 61 | osViModeMpalLpn1, // Individual VI MPAL modes 62 | osViModeMpalLpf1, 63 | osViModeMpalLan1, 64 | osViModeMpalLaf1, 65 | osViModeMpalLpn2, 66 | osViModeMpalLpf2, 67 | osViModeMpalLan2, 68 | osViModeMpalLaf2, 69 | osViModeMpalHpn1, 70 | osViModeMpalHpf1, 71 | osViModeMpalHan1, 72 | osViModeMpalHaf1, 73 | osViModeMpalHpn2, 74 | osViModeMpalHpf2, 75 | osViModeFpalLpn1, // Individual VI FPAL modes 76 | osViModeFpalLpf1, 77 | osViModeFpalLan1, 78 | osViModeFpalLaf1, 79 | osViModeFpalLpn2, 80 | osViModeFpalLpf2, 81 | osViModeFpalLan2, 82 | osViModeFpalLaf2, 83 | osViModeFpalHpn1, 84 | osViModeFpalHpf1, 85 | osViModeFpalHan1, 86 | osViModeFpalHaf1, 87 | osViModeFpalHpn2, 88 | osViModeFpalHpf2 89 | } 90 | 91 | enum Event 92 | { 93 | OS_EVENT_SW1 = 0, /* CPU SW1 interrupt */ 94 | OS_EVENT_SW2 = 1, /* CPU SW2 interrupt */ 95 | OS_EVENT_CART = 2, /* Cartridge interrupt: used by rmon */ 96 | OS_EVENT_COUNTER = 3, /* Counter int: used by VI/Timer Mgr */ 97 | OS_EVENT_SP = 4, /* SP task done interrupt */ 98 | OS_EVENT_SI = 5, /* SI (controller) interrupt */ 99 | OS_EVENT_AI = 6, /* AI interrupt */ 100 | OS_EVENT_VI = 7, /* VI interrupt: used by VI/Timer Mgr */ 101 | OS_EVENT_PI = 8, /* PI interrupt: used by PI Manager */ 102 | OS_EVENT_DP = 9, /* DP full sync interrupt */ 103 | OS_EVENT_CPU_BREAK = 10, /* CPU breakpoint: used by rmon */ 104 | OS_EVENT_SP_BREAK = 11, /* SP breakpoint: used by rmon */ 105 | OS_EVENT_FAULT = 12, /* CPU fault event: used by rmon */ 106 | OS_EVENT_THREADSTATUS = 13, /* CPU thread status: used by rmon */ 107 | OS_EVENT_PRENMI = 14, /* Pre NMI interrupt */ 108 | OS_EVENT_RDB_READ_DONE = 15, /* RDB read ok event: used by rmon */ 109 | OS_EVENT_RDB_LOG_DONE = 16, /* read of log data complete */ 110 | OS_EVENT_RDB_DATA_DONE = 17, /* read of hostio data complete */ 111 | OS_EVENT_RDB_REQ_RAMROM = 18, /* host needs ramrom access */ 112 | OS_EVENT_RDB_FREE_RAMROM = 19, /* host is done with ramrom access */ 113 | OS_EVENT_RDB_DBG_DONE = 20, 114 | OS_EVENT_RDB_FLUSH_PROF = 21, 115 | OS_EVENT_RDB_ACK_PROF = 22 116 | } 117 | } -------------------------------------------------------------------------------- /Decompiled/Program.d: -------------------------------------------------------------------------------- 1 | 2 | import n64; 3 | import std.stdio; 4 | 5 | void main(string[] args) 6 | { 7 | // this file can be directly executed using menu file/compile & run 8 | // phobos and libman imports are allowed 9 | writeln("hello runnable module"); 10 | } 11 | -------------------------------------------------------------------------------- /Decompiled/RAM.d: -------------------------------------------------------------------------------- 1 | module ram; 2 | 3 | public: 4 | 5 | static void StoreByte(byte value, uint address) {} 6 | static void StoreUbyte(ubyte value, uint address) {} 7 | static void StoreShort(short value, uint address) {} 8 | static void StoreUshort(ushort value, uint address) {} 9 | static void StoreWord(int value, uint address) {} 10 | 11 | static byte GetByte(uint address) { return 0 ; } 12 | static ubyte GetUbyte(uint address) { return 0 ; } 13 | static short GetShort(uint address) { return 0 ; } 14 | static ushort GetUshort(uint address) { return 0 ; } 15 | static int GetWord(uint address) { return 0 ; } 16 | 17 | static int x80000300; // If 0 shows "This gamepak is only available for the NSTC..." 18 | 19 | static short x800313c8; 20 | 21 | static short x800313d0; 22 | 23 | static byte x800313e8; 24 | 25 | static byte x800313ec; 26 | 27 | static byte x800313f0; 28 | 29 | static byte x800313f4; 30 | 31 | static short x800313f8; 32 | 33 | static short x800313fc; 34 | 35 | static int x80031420; 36 | 37 | static byte maxHumanDeathsAllowed; // 800314c4 38 | 39 | static ubyte x80031620; 40 | static ubyte x80031621; 41 | static ubyte x80031622; 42 | static ubyte x80031623; 43 | 44 | static short x80031634; 45 | static short x80031636; 46 | 47 | static int x80031b84; 48 | 49 | static int x80034484; 50 | 51 | static int x80035610; 52 | static int x80035614; 53 | 54 | public class OSViMode { 55 | // 0x50 in size 56 | } 57 | static OSViMode[56] osViModes; // 80035630 58 | 59 | static int x80035b5c; 60 | static int x80035b60; 61 | 62 | public static class x80036734 { 63 | static ushort x0; 64 | 65 | static int buffer; // 0x4 66 | static int x8; 67 | 68 | static int x20; 69 | } 70 | 71 | struct UnkWarpPointData 72 | { 73 | short unk_0x0; 74 | short unk_0x2; 75 | ubyte unk_0x4; 76 | ubyte unk_0x5; 77 | short unk_0x6; 78 | } 79 | static UnkWarpPointData[6][5] x8003E000; 80 | 81 | static short x8003e0f0; // Greece boss warp ??? sets x80047f98 82 | static short x8003e0f2; // Java boss warp ??? 83 | static short x8003e0f4; // America boss warp ??? 84 | static short x8003e0f6; // Siberia boss warp ??? 85 | static short x8003e0f8; // Comet boss warp ??? 86 | 87 | static byte x80042da8; 88 | 89 | static int x80047584; // If 0 shows no controller notice at startup 90 | static short controllerOneButtonState; // 80047588 91 | static byte x8004758a; 92 | static byte x8004758b; 93 | 94 | static ushort controllerTwoButtonState; // 8004758e 95 | 96 | static ushort x800475d8; 97 | 98 | static ushort x800475e0; 99 | 100 | static short x800476a0; 101 | static short guess_enablesInput; // 800476a2 102 | 103 | static int x800476c0; 104 | 105 | static short x8004771c; 106 | 107 | static short x80047720; // Debug graph mode 108 | 109 | static byte x80047743; 110 | static byte x80047744; 111 | static byte x80047745; 112 | 113 | static ubyte x8004794c; 114 | 115 | static short x8004794e; 116 | 117 | static float x80047960; 118 | static short x80047964; 119 | 120 | static int x80047968; 121 | 122 | static byte x80047f80; 123 | 124 | static int D_80047F84; 125 | 126 | static int currentLevel; // 80047f90 1=Greece 127 | static int x80047f94; 128 | static int x80047f98; 129 | static int warpPointNumber; // 80047f9c 130 | 131 | static byte x80048024; 132 | static byte x80048025; 133 | static short x80048026; 134 | static short x80048028; 135 | 136 | static int showDemoText; // 80048034 137 | 138 | static byte weaponSlot1; // 80048138 139 | static byte weaponSlot2; 140 | static byte weaponSlot3; 141 | static byte weaponSlot4; 142 | static byte weaponSlot5; 143 | static byte weaponSlot6; 144 | static byte weaponSlot7; 145 | 146 | static byte numHumansEatenToSpawnMutant; // 80048168 147 | 148 | static short D_8004816A; 149 | 150 | static short x8004816e; 151 | static short x80048170; 152 | 153 | static short x80048176; 154 | 155 | static int x80048188; 156 | 157 | static int x8004d150; 158 | static int x8004d154; 159 | static int x8004d158; 160 | 161 | static int x8004dc48; 162 | static int x8004dc4c; 163 | 164 | static short x8004dc60; 165 | 166 | static int indoorRoomLayoutToLoadId; // 80052548 167 | 168 | static int x80052550; 169 | 170 | static int x80052a8c; 171 | static uint millisecondsElapsedInLevel; // x80052a90 172 | static int x80052a94; 173 | struct LevelStats 174 | { 175 | int score; 176 | short secondsElapsed; 177 | short unk_0x6; 178 | } 179 | static LevelStats[6] levelStats; // Why are there 6 levels ?? D_80052A98 180 | 181 | static short x80052ac8; 182 | static byte x80052aca; 183 | static byte x80052acb; // Rendering Flags? 1=Shadows 2=Objects 184 | static ubyte playerModifier; // 80052acd 0=Adam 2=EvilAdam 185 | 186 | static int x80052ad0; 187 | static int x80052ad4; 188 | 189 | static int gameplayMode; // 80052adc 190 | 191 | static int xx80052ad8; 192 | 193 | struct Unk_80052ae8 // 0x44 in size 194 | { 195 | float unk_0x0; 196 | float unk_0x4; 197 | float unk_0x8; 198 | float unk_0xc; 199 | float unk_0x10; 200 | float unk_0x14; 201 | short unk_0x18; 202 | short unk_0x1a; 203 | short unk_0x1c; 204 | short unk_0x1e; 205 | 206 | int unk_0x30; 207 | short unk_0x34; 208 | short unk_0x36; 209 | void* unk_0x38; 210 | short unk_0x3c; 211 | short unk_0x3e; 212 | } 213 | static Unk_80052ae8 x80052ae8; 214 | 215 | static int x80052b2c; 216 | struct object_x80052b2c // object pointed to by 80052b2c 217 | { 218 | float unk_0x0; 219 | float unk_0x4; 220 | float unk_0x8; 221 | float unk_0xc; 222 | 223 | short unk_0x1c; 224 | short unk_0x1e; 225 | } 226 | 227 | static int x80052b34; 228 | struct object_x80052b34 // Object pointed to by 80052b34 229 | { 230 | short x; // 0 231 | short y; // 2 232 | short z; // 4 233 | short unk_0x6; 234 | 235 | ubyte x1a; 236 | } 237 | static int ticksElapsedDuringFrame; // 80052b38 238 | static int x80052b3c; 239 | 240 | static int D_80052B5C; // score ? 241 | 242 | static int x800554d0; 243 | 244 | static int x8005bb2c; 245 | 246 | static int x8005bb48; 247 | static int x8005bb4c; 248 | 249 | 250 | 251 | static int x80067388; 252 | 253 | static int x80067390; 254 | 255 | static int x80067538; 256 | 257 | static int x80067540; 258 | 259 | static int x800676e8; 260 | 261 | static int x800676f0; 262 | 263 | static int x80067898; 264 | 265 | static int x800678a0; 266 | 267 | static short x80068078; 268 | 269 | static int x80068080; 270 | static int videoRenderWidthInPixels; // 80068084 271 | static int x80068088; 272 | static int fractionOfFramebufferWidthRendered; // 8006808c 273 | static float x80068090; // video y scale 274 | 275 | static int x8006809C; 276 | static class object_at_x800680a0 { // object AT 800680a0 277 | public static short x0; 278 | 279 | public static short x20; 280 | 281 | // 0x40 = OSMesgQueue 282 | 283 | // 0x58 = OSMesg[8] 284 | 285 | // 0x78 = OSMesgQueue 286 | 287 | // 0x90 = OSMesg[8] 288 | 289 | public static int x274; 290 | public static int x278; 291 | public static int x260; 292 | public static int x27c; 293 | public static int x264; 294 | public static int x268; 295 | public static int x26c; 296 | public static int x270; 297 | } 298 | 299 | static int x80068328; 300 | static int x8006832c; 301 | 302 | static short x8006c558; 303 | 304 | static float x8008ddf4; 305 | 306 | static float x8008ddfc; 307 | 308 | static short frontEndStateToSwitchTo; // 800946dc 309 | 310 | static short x80094824; 311 | 312 | static short x80094828; 313 | 314 | static short x8009482c; 315 | 316 | static short x80094830; 317 | 318 | static ubyte x800a0968; 319 | 320 | static byte x800a096c; 321 | 322 | static ubyte x800d6d88; 323 | static ubyte x800d6d89; 324 | static ubyte x800d6d8a; 325 | 326 | static int x800d6d8c; 327 | 328 | struct unk_800D6DC0 329 | { 330 | // 0 - 331 | ushort unk_0x12; 332 | ushort unk_0x14; 333 | ubyte unk_0x16; 334 | // - 335 | ubyte unk_0x1c; 336 | // - 337 | ubyte unk_0x26; 338 | // 0x27 339 | short unk_0x28; 340 | // 0x2a 341 | } 342 | static unk_800D6DC0[42] D_800D6DC0; 343 | 344 | static ubyte x800d74a0; 345 | 346 | static ushort x800d74a4; 347 | static ushort x800d74a6; 348 | 349 | static ushort D_800D74AA; 350 | 351 | static float x8008ddf8; 352 | 353 | static float x800e659c; 354 | 355 | static float x800e65a0; 356 | static float x800e65a4; 357 | static int x800e65a8; 358 | static int x800e65ac; 359 | 360 | static int x800e65b8; 361 | 362 | static int x800e65d4; 363 | 364 | static ubyte x800e65ed; 365 | 366 | static int x800e6690; 367 | 368 | static int x800e6694; 369 | static int x800e6698; 370 | static int x800e669c; 371 | 372 | static int x800e66a4; 373 | 374 | static byte x800e6ad8; 375 | 376 | static int x800e6edc; 377 | static int x800e6ee0; 378 | 379 | static float npcAnimationSpeed; // 800e6ee8 380 | 381 | static byte x800e6efd; 382 | 383 | static int x800e7398; 384 | 385 | static byte x800e73de; // Indoor camera location / direction / etc 386 | static ubyte x800e73df; 387 | static short indoorCameraYaw; // 800e73e0 388 | static short indoorCameraPitch; // 800e73e4 389 | static float x800e73e8; 390 | 391 | static float x800e73f0; 392 | static float x800e73f4; 393 | static float x800e73f8; 394 | 395 | static float x800e7410; 396 | static float x800e7414; 397 | static float x800e7418; 398 | 399 | static int x800eae90; 400 | 401 | // 8013b940 cheat struct array[21] 402 | // cheat name = byte[12] 403 | // cheat enable function pointer = uint 404 | 405 | static int x8013d580; 406 | 407 | static int x8013d758; 408 | static int x8013d75c; 409 | 410 | static int x80149398; 411 | static int x8014939c; 412 | 413 | static int x801493a0; 414 | static int x801493a4; 415 | 416 | static short x801493d8; 417 | 418 | static short x801493e0; 419 | static short x801493e2; 420 | 421 | static byte x801493e6; 422 | 423 | static short x80149404; 424 | 425 | static short x80149434; 426 | static short x80149436; 427 | 428 | static short x80149440; 429 | 430 | static int x80149444; 431 | 432 | static int x80149470; 433 | 434 | static int x801494b8; 435 | static ubyte x801494bc; 436 | 437 | static int numberOfMissionConditions; // 80149b28 438 | static int numberOfGameConditions; // 80149b2c 439 | static int numberOfCommands; // 80149b30 440 | static int numberOfMapInfos; // 80149b34 441 | static int numberOfRandomObjects; // 80149b38 442 | static int numberOfDialogueConditions; // 80149b3c 443 | static int numberOfCommandObjects; // 80149b40 444 | static int numberOfCharacters; // 80149b44 445 | static short numberOfMissions; // 80149b48 446 | static short x80149b4a; 447 | 448 | static short x8014ecf0; 449 | 450 | static short x8014ed56; 451 | 452 | static short x80152c90; 453 | 454 | static short x80157590; 455 | 456 | static int x80157a28; 457 | 458 | static short x80157f68; 459 | 460 | static short x80157f96; 461 | 462 | static float x80158e58; // guess_currentAcceleration 463 | 464 | static int x80159300; 465 | 466 | static int x80159320; 467 | 468 | class Object80222a78 // 0x10 in size 469 | { 470 | public int x0; 471 | public int x4; 472 | public int x8; 473 | public int xc; 474 | } 475 | 476 | static Object80222a78[] x80222a78; 477 | 478 | class AlienWave // 0x14 in size 479 | { 480 | public ubyte waveType; 481 | // byte 482 | public short xPosition; 483 | public short yPosition; 484 | // short 485 | // 3 more words of data 486 | } 487 | 488 | static int nextTrigger; // 80223778 489 | 490 | static AlienWave[] alienWaves; // 80223780 491 | 492 | static int x80224680; 493 | 494 | struct Unk_80259490 495 | { 496 | short unk_0x0; 497 | short unk_0x2; 498 | 499 | short unk_0x8; 500 | } 501 | static Unk_80259490 x80259490; -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # docker run -it --rm -v /sm64:/app/src -w /app/src n64split_build:latest make 2 | # If error about QEMU_IRIX do bash instead of make, then make inside the image 3 | # /sm64 is the docker-accessible folder containing the decomp repo 4 | FROM ubuntu:18.04 5 | 6 | WORKDIR /bin 7 | 8 | #COPY . /bin 9 | COPY qemu-irix /bin 10 | 11 | WORKDIR / 12 | 13 | RUN apt-get update && apt-get install -y \ 14 | binutils-mips-linux-gnu \ 15 | build-essential \ 16 | git \ 17 | libcapstone3 \ 18 | libglib2.0-dev \ 19 | libpixman-1-dev \ 20 | make \ 21 | pkg-config \ 22 | python3 \ 23 | zlib1g-dev 24 | 25 | RUN echo "export QEMU_IRIX=/bin/qemu-irix" >> ~/.bashrc 26 | 27 | # Preparing VirtualBox to Share Folders 28 | # To achieve this, the folder (e.g. H:\work) needs to be shared with the VirtualBox virtual machine named default, before it can be mounted as a volume within a Docker container. There may be other approaches, but here are the steps for our particular set-up: 29 | # Open "Docker Quickstart Terminal". 30 | # Once Docker is running, type docker-machine stop default. 31 | # Open the Command Line from the start menu (search for cmd.exe). 32 | # Navigate to the VirtualBox folder using cd C:/Program Files/Oracle/VirtualBox 33 | # Type VBoxManage.exe sharedfolder add default --name "h/work" --hostpath "\\?\h:\work" --automount 34 | 35 | # At above step change name var to what you'll pass in to docker run -v 36 | 37 | # Type VBoxManage.exe setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root 1 38 | # Type VBoxManage.exe setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/h/work 1 39 | # 40 | # The above steps will prepare VirtualBox for sharing H:\work. Now we need to mount the directory inside our docker-machine: 41 | # Open "Docker Quickstart Terminal". 42 | # Once Docker is running, type docker-machine ssh default 43 | # Type sudo mkdir --parents /h/work 44 | # Type sudo mount -t vboxsf h/work /h/work/ 45 | # Type exit 46 | # 47 | # You can now create Docker container instances and share the H:\work folder with them as a mounted volume. Let's demonstrate this with jupyter/scipy-notebook 48 | # Sharing Folders with a Docker Container 49 | # 50 | # To create a Docker container from the jupyter/scipy-notebook image, type the following command and wait for it to complete execution: docker run --name="scipy" --user root -v /h/work:/home/jovyan -d -e GRANT_SUDO=yes -p 8888:8888 jupyter/scipy-notebook start-notebook.sh --NotebookApp.token='' -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to rebuild SM64 split image 2 | 3 | ### Default target ### 4 | 5 | default: clean all 6 | 7 | ### Build Options ### 8 | # Version of the game to build and graphics microcode used 9 | # If COMPARE is 1, check the output sha1sum when building 'all' 10 | # If NON_MATCHING is 1, define the NON_MATCHING macro when building 11 | NON_MATCHING ?= 0 12 | # If ENDIAN_IND is 1, enable non-matching code changes that try to ensure 13 | # endianness independence 14 | ENDIAN_IND ?= 0 15 | 16 | # Release 17 | 18 | TARGET := body_harvest.u 19 | 20 | # Microcode 21 | 22 | ################ Target Executable and Sources ############### 23 | 24 | # BUILD_DIR is location where all build artifacts are placed 25 | BUILD_DIR_BASE := build 26 | BUILD_DIR := $(BUILD_DIR_BASE) 27 | 28 | LIBULTRA := $(BUILD_DIR)/libultra.a 29 | ROM := $(TARGET).z64 30 | ELF := $(BUILD_DIR)/$(TARGET).elf 31 | LD_SCRIPT := body_harvest.u.ld 32 | TEXTURE_DIR := textures 33 | ACTOR_DIR := actors 34 | 35 | # Directories containing source files 36 | SRC_DIRS := src src/base 37 | ASM_DIRS := asm 38 | BIN_DIRS := bin 39 | 40 | ULTRA_SRC_DIRS := lib/src lib/src/math 41 | ULTRA_ASM_DIRS := lib/asm lib/data 42 | ULTRA_BIN_DIRS := lib/bin 43 | 44 | LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.s))) 45 | 46 | MIPSISET := -mips2 -32 47 | 48 | OPT_FLAGS := -O2 49 | 50 | 51 | # File dependencies and variables for specific files 52 | include Makefile.split 53 | 54 | # Source code files 55 | C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) 56 | S_FILES := $(foreach dir,$(ASM_DIRS),$(wildcard $(dir)/*.s)) 57 | ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c)) 58 | ULTRA_S_FILES := $(foreach dir,$(ULTRA_ASM_DIRS),$(wildcard $(dir)/*.s)) 59 | LEVEL_S_FILES := $(addsuffix header.s,$(addprefix bin/,$(LEVEL_DIRS))) 60 | SEG_IN_FILES := $(foreach dir,$(BIN_DIRS),$(wildcard $(dir)/*.s.in)) 61 | SEG_S_FILES := $(foreach dir,$(BIN_DIRS),$(wildcard $(dir)/*.s)) \ 62 | $(foreach file,$(SEG_IN_FILES),$(file:.s.in=.s)) 63 | 64 | # Object files 65 | O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \ 66 | $(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \ 67 | $(foreach file,$(LEVEL_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) 68 | 69 | ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \ 70 | $(foreach file,$(ULTRA_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) 71 | 72 | # Automatic dependency files 73 | DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) 74 | 75 | # Files with NON_MATCHING ifdefs 76 | NON_MATCHING_C_FILES != grep -rl NON_MATCHING $(wildcard src/audio/*.c) 77 | NON_MATCHING_O_FILES = $(foreach file,$(NON_MATCHING_C_FILES),$(BUILD_DIR)/$(file:.c=.o)) 78 | NON_MATCHING_DEP = $(BUILD_DIR)/src/audio/non_matching_dep 79 | 80 | # Segment elf files 81 | SEG_FILES := $(foreach file,$(SEG_S_FILES),$(BUILD_DIR)/$(file:.s=.elf)) 82 | 83 | ##################### Compiler Options ####################### 84 | IRIX_ROOT := tools/ido5.3_compiler 85 | 86 | ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0) 87 | CROSS := mips-linux-gnu- 88 | else 89 | CROSS := mips64-elf- 90 | endif 91 | 92 | AS := $(CROSS)as 93 | CC := $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc 94 | CPP := cpp -P 95 | LD := $(CROSS)ld 96 | AR := $(CROSS)ar 97 | OBJDUMP := $(CROSS)objdump 98 | OBJCOPY := $(CROSS)objcopy 99 | 100 | # Check code syntax with host compiler 101 | CC_CHECK := gcc -fsyntax-only -fsigned-char -nostdinc -I include -I $(BUILD_DIR)/include -I src -std=gnu90 -Wall -Wextra -Wno-format-security -D_LANGUAGE_C 102 | 103 | ASFLAGS := -march=vr4300 -mabi=32 -I include -I $(BUILD_DIR) 104 | CFLAGS = -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -Xfullwarn $(OPT_FLAGS) -signed -I include -I $(BUILD_DIR)/include -I src -D_LANGUAGE_C $(MIPSISET) 105 | OBJCOPYFLAGS := 106 | SYMBOL_LINKING_FLAGS := $(addprefix -R ,$(SEG_FILES)) 107 | LDFLAGS := -T undefined_syms.txt -T $(LD_SCRIPT) -Map $(BUILD_DIR)/body_harvest.u.map --no-check-sections $(SYMBOL_LINKING_FLAGS) 108 | 109 | ifeq ($(shell getconf LONG_BIT), 32) 110 | # Work around memory allocation bug in QEMU 111 | export QEMU_GUEST_BASE := 1 112 | else 113 | # Ensure that gcc treats the code as 32-bit 114 | CC_CHECK += -m32 115 | endif 116 | 117 | ####################### Other Tools ######################### 118 | 119 | # N64 tools 120 | TOOLS_DIR = tools 121 | N64CKSUM = $(TOOLS_DIR)/n64cksum 122 | N64GRAPHICS = $(TOOLS_DIR)/n64graphics 123 | N64GRAPHICS_CI = $(TOOLS_DIR)/n64graphics_ci 124 | TEXTCONV = $(TOOLS_DIR)/textconv 125 | IPLFONTUTIL = $(TOOLS_DIR)/iplfontutil 126 | EMULATOR = mupen64plus 127 | EMU_FLAGS = --noosd 128 | LOADER = loader64 129 | LOADER_FLAGS = -vwf 130 | SHA1SUM = sha1sum 131 | 132 | # Make tools if out of date 133 | DUMMY != make -s -C tools >&2 134 | 135 | ###################### Dependency Check ##################### 136 | 137 | BINUTILS_VER_MAJOR := $(shell $(LD) --version | grep ^GNU | sed 's/^.* //; s/\..*//g') 138 | BINUTILS_VER_MINOR := $(shell $(LD) --version | grep ^GNU | sed 's/^[^.]*\.//; s/\..*//g') 139 | BINUTILS_DEPEND := $(shell expr $(BINUTILS_VER_MAJOR) \>= 2 \& $(BINUTILS_VER_MINOR) \>= 27) 140 | ifeq ($(BINUTILS_DEPEND),0) 141 | $(error binutils version 2.27 required, version $(BINUTILS_VER_MAJOR).$(BINUTILS_VER_MINOR) detected) 142 | endif 143 | 144 | ifndef QEMU_IRIX 145 | $(error env variable QEMU_IRIX should point to the qemu-mips binary) 146 | endif 147 | 148 | ######################## Targets ############################# 149 | 150 | all: $(ROM) 151 | 152 | clean: 153 | find $(BUILD_DIR_BASE) -type f -delete 154 | 155 | test: $(ROM) 156 | $(EMULATOR) $(EMU_FLAGS) $< 157 | 158 | load: $(ROM) 159 | $(LOADER) $(LOADER_FLAGS) $< 160 | 161 | libultra: $(BUILD_DIR)/libultra.a 162 | 163 | ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) include) 164 | 165 | # Make sure build directory exists before compiling anything 166 | DUMMY != mkdir -p $(ALL_DIRS) 167 | 168 | # compressed segment generation 169 | $(BUILD_DIR)/bin/%.o: bin/%.s 170 | $(AS) $(ASFLAGS) --no-pad-sections -o $@ $< 171 | 172 | # Rebuild files with '#ifdef NON_MATCHING' when that macro changes. 173 | $(NON_MATCHING_O_FILES): $(NON_MATCHING_DEP).$(NON_MATCHING) 174 | $(NON_MATCHING_DEP).$(NON_MATCHING): 175 | @rm -f $(NON_MATCHING_DEP).* 176 | touch $@ 177 | 178 | $(BUILD_DIR)/lib/src/math/%.o: lib/src/math/%.c 179 | @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/lib/src/math/$*.d $< 180 | $(CC) -c $(CFLAGS) -o $@ $< 181 | tools/patch_libultra_math $@ || rm $@ 182 | 183 | $(BUILD_DIR)/%.o: %.c 184 | @$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $< 185 | $(CC) -c $(CFLAGS) -o $@ $< 186 | 187 | 188 | $(BUILD_DIR)/%.o: %.s 189 | $(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ $< 190 | 191 | $(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT) 192 | $(CPP) -I include/ -DBUILD_DIR=$(BUILD_DIR) -o $@ $< 193 | 194 | $(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES) 195 | $(AR) rcs -o $@ $(ULTRA_O_FILES) 196 | 197 | $(ELF): $(BUILD_DIR)/$(TARGET).o $(O_FILES) $(LD_SCRIPT) 198 | $(LD) $(LDFLAGS) -o $@ $< $(LIBS) 199 | 200 | $(ROM): $(ELF) 201 | $(OBJCOPY) $(OBJCOPYFLAGS) $< $(@:.z64=.bin) -O binary 202 | $(N64CKSUM) $(@:.z64=.bin) $@ 203 | 204 | $(BUILD_DIR)/$(TARGET).objdump: $(ELF) 205 | $(OBJDUMP) -D $< > $@ 206 | 207 | 208 | 209 | .PHONY: all clean default diff test load libultra 210 | .PRECIOUS: $(BUILD_DIR)/bin/%.elf 211 | 212 | # Remove built-in rules, to improve performance 213 | MAKEFLAGS += --no-builtin-rules 214 | 215 | -include $(DEP_FILES) 216 | 217 | print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true 218 | -------------------------------------------------------------------------------- /Makefile.split: -------------------------------------------------------------------------------- 1 | TARGET = body_harvest.u 2 | LD_SCRIPT = $(TARGET).ld 3 | MIO0_DIR = bin 4 | TEXTURE_DIR = textures 5 | GEO_DIR = geo 6 | LEVEL_DIR = levels 7 | 8 | MUSIC_DIR = music 9 | 10 | 11 | 12 | MIO0_FILES = 13 | 14 | LEVEL_FILES = 15 | 16 | MUSIC_FILES = -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bodyharvestdecomp 2 | 3 | Decompilation of Body Harvest for the Nintendo 64. 4 | 5 | ## Setup 6 | Clone the repo. 7 | Use the .yaml to split a Body Harvest (U) ROM with [N64Split](https://github.com/queueRAM/sm64tools). 8 | Copy the bin folder from the split output to the repo. 9 | Either use the dockerfile itself, or read it to see how to setup a build environment. 10 | You'll need qemu-irix in the same location as the dockerfile when you build it. 11 | ``` 12 | docker build -t n64split_build . 13 | docker run -it --rm -v /sm64:/app/src -w /app/src n64split_build:latest make 14 | ``` 15 | Where /sm64 is the shared folder on your pc where you've put the repo. 16 | You may need to read the instructions in the dockerfile on sharing a folder if you're running via virtualbox. 17 | If you get an error about qemu-irix run: 18 | ``` 19 | docker run -it --rm -v /sm64:/app/src -w /app/src n64split_build:latest bash 20 | ``` 21 | And then run make in the terminal. 22 | This should build a 1:1 ROM in the repo dir. 23 | 24 | ## Notes 25 | 26 | Currently only two functions are written in c. 27 | The majority of the work is in /Decompiled where I've been rewriting functions in d. 28 | This isn't currently compiled into the ROM, though in theory you can compile d to MIPS if you know more than me. 29 | 30 | ## Questions 31 | Why are you using a janky hack of the Super Mario 64 decomp makefile? 32 | I don't know any better, help is welcome, especially if you know how to setup a compiler that will compile the ld and sd operations in the ROM. I've had to change them to data in the .s file so the compiler doesn't turn them into two sw or lw. -------------------------------------------------------------------------------- /body_harvest.u.ld: -------------------------------------------------------------------------------- 1 | /* Body Harvest (U) linker script 2 | * generated by n64split v0.4a - N64 ROM splitter */ 3 | 4 | OUTPUT_ARCH (mips) 5 | 6 | SECTIONS 7 | { 8 | /* header and boot */ 9 | .header 0x0 : AT(0x0) { 10 | * (.header); 11 | * (.boot); 12 | } 13 | 14 | /* 0x80000450 001050-02EA10 [2DA10] */ 15 | .text80000450 0x80000400 : AT(0x001000) SUBALIGN(4) { 16 | * (.text80000400); 17 | build/src/base/EF98.o(.text); 18 | * (.text8000EFB8); 19 | build/src/base/F618.o(.text); 20 | * (.text8000F648); 21 | } 22 | 23 | /* Functions that don't produce 1:1 asm */ 24 | /*.3584 0x80004184 : AT(0x003584) SUBALIGN(4) { 25 | build/src/base/3584.o(.text); 26 | } 27 | .EF10 0x8000EF10 : AT(0x00FB10) SUBALIGN(4) { 28 | build/src/base/EF10.o(.text); 29 | } 30 | .EFB8 0x8000EFB8 : AT(0x00FBB8) SUBALIGN(4) { 31 | build/src/base/EFB8.o(.text); 32 | }*/ 33 | 34 | /* 0x80070270 040720-060E5C [2073C] */ 35 | .text80070270 0x80070270 : AT(0x040720) { 36 | * (.text80070270); 37 | } 38 | 39 | /* 0x802D4CD0 18D7E0-195C80 [84A0] */ 40 | .text802D4CD0 0x802D4CD0 : AT(0x18D7E0) { 41 | * (.text802D4CD0); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /geo_commands.inc: -------------------------------------------------------------------------------- 1 | # geo layout macros 2 | 3 | # 0x00: Branch and store return address 4 | # 0x04: scriptTarget, segment address of geo layout 5 | .macro geo_branch_and_link scriptTarget 6 | .byte 0x00, 0x00, 0x00, 0x00 7 | .word \scriptTarget 8 | .endm 9 | 10 | # 0x01: Terminate geo layout 11 | # 0x01-0x03: unused 12 | .macro geo_end 13 | .byte 0x01, 0x00, 0x00, 0x00 14 | .endm 15 | 16 | # 0x02: Branch 17 | # 0x01: if 1, store next geo layout address on stack 18 | # 0x02-0x03: unused 19 | # 0x04: scriptTarget, segment address of geo layout 20 | .macro geo_branch type, scriptTarget 21 | .byte 0x02, \type, 0x00, 0x00 22 | .word \scriptTarget 23 | .endm 24 | 25 | # 0x03: Return from branch 26 | # 0x01-0x03: unused 27 | .macro geo_return 28 | .byte 0x03, 0x00, 0x00, 0x00 29 | .endm 30 | 31 | # 0x04: Open node 32 | # 0x01-0x03: unused 33 | .macro geo_open_node 34 | .byte 0x04, 0x00, 0x00, 0x00 35 | .endm 36 | 37 | # 0x05: Close node 38 | # 0x01-0x03: unused 39 | .macro geo_close_node 40 | .byte 0x05, 0x00, 0x00, 0x00 41 | .endm 42 | 43 | # 0x06: TODO 44 | # 0x01: unused 45 | # 0x02: s16, index of some array 46 | .macro geo_todo_06 param 47 | .byte 0x06, 0x00 48 | .hword \param 49 | .endm 50 | 51 | # 0x07: Update current scene graph node flags 52 | # 0x01: u8 operation (0 = reset, 1 = set, 2 = clear) 53 | # 0x02: s16 bits 54 | .macro geo_update_node_flags operation, flagBits 55 | .byte 0x07, \operation 56 | .hword \flagBits 57 | .endm 58 | 59 | # 0x08: Create screen area scene graph node 60 | # 0x01: unused 61 | # 0x02: s16 num entries (+2) to allocate 62 | # 0x04: s16 x 63 | # 0x06: s16 y 64 | # 0x08: s16 width 65 | # 0x0A: s16 height 66 | .macro geo_node_screen_area numEntries, x, y, width, height 67 | .byte 0x08, 0x00 68 | .hword \numEntries 69 | .hword \x, \y, \width, \height 70 | .endm 71 | 72 | # 0x09: TODO Create ? scene graph node 73 | # 0x02: s16 ? 74 | .macro geo_todo_09 param 75 | .byte 0x09, 0x00 76 | .hword \param 77 | .endm 78 | 79 | # 0x0A: Create camera frustum scene graph node 80 | # 0x01: u8 if nonzero, enable function field 81 | # 0x02: s16 field of view 82 | # 0x04: s16 near 83 | # 0x06: s16 far 84 | # 0x08: [GraphNodeFunc function] 85 | .macro geo_camera_frustum fov, near, far, function=0 86 | .byte 0x0A 87 | .if (\function != 0) 88 | .byte 0x01 89 | .else 90 | .byte 0x00 91 | .endif 92 | .hword \fov, \near, \far 93 | .if (\function != 0) 94 | .word \function 95 | .endif 96 | .endm 97 | 98 | # 0x0B: Create a root scene graph node 99 | # 0x01-0x03: unused 100 | .macro geo_node_start 101 | .byte 0x0B, 0x00, 0x00, 0x00 102 | .endm 103 | 104 | # 0x0C: Create zbuffer-toggling scene graph node 105 | # 0x01: u8 enableZBuffer (1 = on, 0 = off) 106 | # 0x02-0x03: unused 107 | .macro geo_zbuffer enable 108 | .byte 0x0C, \enable, 0x00, 0x00 109 | .endm 110 | 111 | # 0x0D: Create render range scene graph node 112 | # 0x01-0x03: unused 113 | # 0x04: s16 minDistance 114 | # 0x06: s16 maxDistance 115 | .macro geo_render_range minDistance, maxDistance 116 | .byte 0x0D, 0x00, 0x00, 0x00 117 | .hword \minDistance, \maxDistance 118 | .endm 119 | 120 | # 0x0E: Create switch-case scene graph node 121 | # 0x01: unused 122 | # 0x02: s16 numCases 123 | # 0x04: GraphNodeFunc caseSelectorFunc 124 | .macro geo_switch_case count, function 125 | .byte 0x0E, 0x00 126 | .hword \count 127 | .word \function 128 | .endm 129 | 130 | # 0x0F: TODO Create ? scene graph node 131 | # 0x01: unused 132 | # 0x02: s16 ? 133 | # 0x04: s16 unkX 134 | # 0x06: s16 unkY 135 | # 0x08: s16 unkZ 136 | # 0x0A: s16 unkX_2 137 | # 0x0C: s16 unkY_2 138 | # 0x0E: s16 unkZ_2 139 | # 0x10: GraphNodeFunc function 140 | .macro geo_todo_0F unknown, x1, y1, z1, x2, y2, z2, function 141 | .byte 0x0F, 0x00 142 | .hword \unknown, \x1, \y1, \z1, \x2, \y2, \z2 143 | .word \function 144 | .endm 145 | 146 | # 0x10: Create translation & rotation scene graph node with optional display list 147 | # Four different versions of 0x10 148 | # cmd+0x01: u8 params 149 | # 0b1000_0000: if set, enable displayList field and drawingLayer 150 | # 0b0111_0000: fieldLayout (determines how rest of data is formatted 151 | # 0b0000_1111: drawingLayer 152 | # 153 | # fieldLayout = 0: Translate & Rotate 154 | # 0x04: s16 xTranslation 155 | # 0x06: s16 xTranslation 156 | # 0x08: s16 xTranslation 157 | # 0x0A: s16 xRotation 158 | # 0x0C: s16 xRotation 159 | # 0x0E: s16 xRotation 160 | # 0x10: [u32 displayList: if MSbit of params set, display list segmented address] 161 | .macro geo_translate_rotate layer, tx, ty, tz, rx, ry, rz, displayList=0 162 | .byte 0x10 163 | .if (\displayList != 0) 164 | .byte 0x00 | \layer | 0x80 165 | .else 166 | .byte 0x00 | \layer 167 | .endif 168 | .hword 0x0000 169 | .hword \tx, \ty, \tz 170 | .hword \rx, \ry, \rz 171 | .if (\displayList != 0) 172 | .word \displayList 173 | .endif 174 | .endm 175 | 176 | # fieldLayout = 1: Translate 177 | # 0x02: s16 xTranslation 178 | # 0x04: s16 yTranslation 179 | # 0x06: s16 zTranslation 180 | # 0x08: [u32 displayList: if MSbit of params set, display list segmented address] 181 | .macro geo_translate layer, tx, ty, tz, displayList=0 182 | .byte 0x10 183 | .if (\displayList != 0) 184 | .byte 0x10 | \layer | 0x80 185 | .else 186 | .byte 0x10 | \layer 187 | .endif 188 | .hword \tx, \ty, \tz 189 | .if (\displayList != 0) 190 | .word \displayList 191 | .endif 192 | .endm 193 | 194 | # fieldLayout = 2: Rotate 195 | # 0x02: s16 xRotation 196 | # 0x04: s16 yRotation 197 | # 0x06: s16 zRotation 198 | # 0x08: [u32 displayList: if MSbit of params set, display list segmented address] 199 | .macro geo_rotate layer, rx, ry, rz, displayList=0 200 | .byte 0x10 201 | .if (\displayList != 0) 202 | .byte 0x20 | \layer | 0x80 203 | .else 204 | .byte 0x20 | \layer 205 | .endif 206 | .hword \rx, \ry, \rz 207 | .if (\displayList != 0) 208 | .word \displayList 209 | .endif 210 | .endm 211 | 212 | # fieldLayout = 3: Rotate Y 213 | # 0x02: s16 yRotation 214 | # 0x04: [u32 displayList: if MSbit of params set, display list segmented address] 215 | .macro geo_rotate_y layer, ry, displayList=0 216 | .byte 0x10 217 | .if (\displayList != 0) 218 | .byte 0x30 | \layer | 0x80 219 | .else 220 | .byte 0x30 | \layer 221 | .endif 222 | .hword \ry 223 | .if (\displayList != 0) 224 | .word \displayList 225 | .endif 226 | .endm 227 | 228 | # 0x11: TODO Create ? scene graph node with optional display list 229 | # 0x01: u8 params 230 | # 0b1000_0000: if set, enable displayList field and drawingLayer 231 | # 0b0000_1111: drawingLayer 232 | # 0x02: s16 unkX 233 | # 0x04: s16 unkY 234 | # 0x06: s16 unkZ 235 | # 0x08: [u32 displayList: if MSbit of params set, display list segmented address] 236 | .macro geo_todo_11 layer, ux, uy, uz, displayList=0 237 | .byte 0x11 238 | .if (\displayList != 0) 239 | .byte 0x80 | \layer 240 | .else 241 | .byte 0x00 242 | .endif 243 | .hword \ux, \uy, \uz 244 | .if (\displayList != 0) 245 | .word \displayList 246 | .endif 247 | .endm 248 | 249 | # 0x12: TODO Create ? scene graph node 250 | # 0x01: u8 params 251 | # 0b1000_0000: if set, enable displayList field and drawingLayer 252 | # 0b0000_1111: drawingLayer 253 | # 0x02: s16 unkX 254 | # 0x04: s16 unkY 255 | # 0x06: s16 unkZ 256 | # 0x08: [u32 displayList: if MSbit of params set, display list segmented address] 257 | .macro geo_todo_12 layer, ux, uy, uz, displayList=0 258 | .byte 0x12 259 | .if (\displayList != 0) 260 | .byte 0x80 | \layer 261 | .else 262 | .byte 0x00 263 | .endif 264 | .hword \ux, \uy, \uz 265 | .if (\displayList != 0) 266 | .word \displayList 267 | .endif 268 | .endm 269 | 270 | # 0x13: Create display list scene graph node with translation 271 | # 0x01: u8 drawingLayer 272 | # 0x02: s16 xTranslation 273 | # 0x04: s16 yTranslation 274 | # 0x06: s16 zTranslation 275 | # 0x08: u32 displayList: dislay list segmented address 276 | .macro geo_dl_translated layer, x, y, z, displayList=0 277 | .byte 0x13, \layer 278 | .hword \x, \y, \z 279 | .word \displayList 280 | .endm 281 | 282 | # 0x14: Create billboarding node with optional display list 283 | # 0x01: u8 params 284 | # 0b1000_0000: if set, enable displayList field and drawingLayer 285 | # 0b0000_1111: drawingLayer 286 | # 0x02: s16 xTranslation 287 | # 0x04: s16 yTranslation 288 | # 0x06: s16 zTranslation 289 | # 0x08: [u32 displayList: if MSbit of params is set, display list segmented address] 290 | .macro geo_billboard layer=0, tx=0, ty=0, tz=0, displayList=0 291 | .byte 0x14 292 | .if (\displayList != 0) 293 | .byte 0x80 | \layer 294 | .else 295 | .byte 0x00 296 | .endif 297 | .hword \tx, \ty, \tz 298 | .if (\displayList != 0) 299 | .word \displayList 300 | .endif 301 | .endm 302 | 303 | # 0x15: Create plain display list scene graph node 304 | # 0x01: u8 drawingLayer 305 | # 0x02=0x03: unused 306 | # 0x04: u32 displayList: display list segmented address 307 | .macro geo_display_list layer, displayList 308 | .byte 0x15, \layer, 0x00, 0x00 309 | .word \displayList 310 | .endm 311 | 312 | # 0x16: Create shadow scene graph node 313 | # 0x01: unused 314 | # 0x02: s16 shadowType (cast to u8) 315 | # 0x04: s16 shadowSolidity (cast to u8) 316 | # 0x06: s16 shadowScale 317 | .set SHADOW_CIRCLE_UNK0, 0x00 318 | .set SHADOW_CIRCLE_UNK1, 0x01 319 | .set SHADOW_CIRCLE_UNK2, 0x02 # unused shadow type 320 | .set SHADOW_SQUARE_PERMANENT, 0x0A # square shadow that never disappears 321 | .set SHADOW_SQUARE_SCALABLE, 0x0B # square shadow, shrinks with distance 322 | .set SHADOW_SQUARE_TOGGLABLE, 0x0C # square shadow, disappears with distance 323 | .set SHADOW_CIRCLE_PLAYER, 0x63 # player (Mario) shadow 324 | .set SHADOW_RECTANGLE_HARDCODED_OFFSET, 0x32 # offset of hard-coded shadows 325 | .macro geo_shadow type, solidity, scale 326 | .byte 0x16, 0x00 327 | .hword \type, \solidity, \scale 328 | .endm 329 | 330 | # 0x17: TODO Create ? scene graph node 331 | # 0x01-0x03: unused 332 | .macro geo_todo_17 333 | .byte 0x17, 0x00, 0x00, 0x00 334 | .endm 335 | 336 | # 0x18: Create ? scene graph node 337 | # 0x01: unused 338 | # 0x02: s16 parameter 339 | # 0x04: GraphNodeFunc function 340 | .macro geo_asm param, function 341 | .byte 0x18, 0x00 342 | .hword \param 343 | .word \function 344 | .endm 345 | 346 | # 0x19: Create background scene graph node 347 | # 0x02: s16 background: background ID, or RGBA5551 color if backgroundFunc is null 348 | # 0x04: GraphNodeFunc backgroundFunc 349 | .macro geo_background param, function=0 350 | .byte 0x19, 0x00 351 | .hword \param 352 | .word \function 353 | .endm 354 | 355 | # 0x1A: No operation 356 | .macro geo_nop_1A 357 | .byte 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 358 | .endm 359 | 360 | # 0x1B: TODO Create ? scene graph node 361 | # 0x02: s16 index of array 362 | .macro geo_todo_1B param 363 | .byte 0x1B, 0x00 364 | .hword \param 365 | .endm 366 | 367 | # 0x1C: TODO Create ? scene graph node 368 | # 0x01: u8 unk01 369 | # 0x02: s16 unkX 370 | # 0x04: s16 unkY 371 | # 0x06: s16 unkZ 372 | # 0x08: GraphNodeFunc nodeFunc 373 | .macro geo_todo_1C param, ux, uy, uz, nodeFunc 374 | .byte 0x1C, \param 375 | .hword \ux, \uy, \uz 376 | .word \nodeFunc 377 | .endm 378 | 379 | # 0x1D: Create scale scene graph node with optional display list 380 | # 0x01: u8 params 381 | # 0b1000_0000: if set, enable displayList field and drawingLayer 382 | # 0b0000_1111: drawingLayer 383 | # 0x02-0x03: unused 384 | # 0x04: u32 scale (0x10000 = 1.0) 385 | # 0x08: [u32 displayList: if MSbit of params is set, display list segment address] 386 | .macro geo_scale layer, scale, displayList=0 387 | .byte 0x1D 388 | .if (\displayList != 0) 389 | .byte 0x80 | \layer 390 | .else 391 | .byte 0x00 392 | .endif 393 | .byte 0x00, 0x00 394 | .word \scale 395 | .if (\displayList != 0) 396 | .word \displayList 397 | .endif 398 | .endm 399 | 400 | # 0x1E: No operation 401 | .macro geo_nop_1E 402 | .byte 0x1E, 0x00, 0x00, 0x00 403 | .byte 0x00, 0x00, 0x00, 0x00 404 | .endm 405 | 406 | # 0x1F: No operation 407 | .macro geo_nop_1F 408 | .byte 0x1F, 0x00, 0x00, 0x00 409 | .byte 0x00, 0x00, 0x00, 0x00 410 | .byte 0x00, 0x00, 0x00, 0x00 411 | .byte 0x00, 0x00, 0x00, 0x00 412 | .endm 413 | 414 | # 0x20: Create render distance scene graph node (unconfirmed?) 415 | # 0x01: unused 416 | # 0x02: s16 renderDistance? 417 | .macro geo_start_distance renderDistance 418 | .byte 0x20, 0x00 419 | .hword \renderDistance 420 | .endm 421 | 422 | -------------------------------------------------------------------------------- /globals.inc: -------------------------------------------------------------------------------- 1 | # globally accessible functions and data 2 | # these will be accessible by C code and show up in the .map file 3 | 4 | 5 | -------------------------------------------------------------------------------- /include/PR/abi.h: -------------------------------------------------------------------------------- 1 | #ifndef _ABI_H_ 2 | #define _ABI_H_ 3 | 4 | /************************************************************************** 5 | * * 6 | * Copyright (C) 1994, Silicon Graphics, Inc. * 7 | * * 8 | * These coded instructions, statements, and computer programs contain * 9 | * unpublished proprietary information of Silicon Graphics, Inc., and * 10 | * are protected by Federal copyright law. They may not be disclosed * 11 | * to third parties or copied or duplicated in any form, in whole or * 12 | * in part, without the prior written consent of Silicon Graphics, Inc. * 13 | * * 14 | **************************************************************************/ 15 | 16 | /************************************************************************** 17 | * 18 | * $Revision: 1.32 $ 19 | * $Date: 1997/02/11 08:16:37 $ 20 | * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/abi.h,v $ 21 | * 22 | **************************************************************************/ 23 | 24 | /* 25 | * Header file for the Audio Binary Interface. 26 | * This is included in the Media Binary Interface file 27 | * mbi.h. 28 | * 29 | * This file follows the framework used for graphics. 30 | * 31 | */ 32 | 33 | /* Audio commands: */ 34 | #define A_SPNOOP 0 35 | #define A_ADPCM 1 36 | #define A_CLEARBUFF 2 37 | #define A_ENVMIXER 3 38 | #define A_LOADBUFF 4 39 | #define A_RESAMPLE 5 40 | #define A_SAVEBUFF 6 41 | #define A_SEGMENT 7 42 | #define A_SETBUFF 8 43 | #define A_SETVOL 9 44 | #define A_DMEMMOVE 10 45 | #define A_LOADADPCM 11 46 | #define A_MIXER 12 47 | #define A_INTERLEAVE 13 48 | #define A_POLEF 14 49 | #define A_SETLOOP 15 50 | 51 | #define ACMD_SIZE 32 52 | /* 53 | * Audio flags 54 | */ 55 | 56 | #define A_INIT 0x01 57 | #define A_CONTINUE 0x00 58 | #define A_LOOP 0x02 59 | #define A_OUT 0x02 60 | #define A_LEFT 0x02 61 | #define A_RIGHT 0x00 62 | #define A_VOL 0x04 63 | #define A_RATE 0x00 64 | #define A_AUX 0x08 65 | #define A_NOAUX 0x00 66 | #define A_MAIN 0x00 67 | #define A_MIX 0x10 68 | 69 | /* 70 | * BEGIN C-specific section: (typedef's) 71 | */ 72 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 73 | 74 | /* 75 | * Data Structures. 76 | */ 77 | 78 | typedef struct { 79 | unsigned int cmd:8; 80 | unsigned int flags:8; 81 | unsigned int gain:16; 82 | unsigned int addr; 83 | } Aadpcm; 84 | 85 | typedef struct { 86 | unsigned int cmd:8; 87 | unsigned int flags:8; 88 | unsigned int gain:16; 89 | unsigned int addr; 90 | } Apolef; 91 | 92 | typedef struct { 93 | unsigned int cmd:8; 94 | unsigned int flags:8; 95 | unsigned int pad1:16; 96 | unsigned int addr; 97 | } Aenvelope; 98 | 99 | typedef struct { 100 | unsigned int cmd:8; 101 | unsigned int pad1:8; 102 | unsigned int dmem:16; 103 | unsigned int pad2:16; 104 | unsigned int count:16; 105 | } Aclearbuff; 106 | 107 | typedef struct { 108 | unsigned int cmd:8; 109 | unsigned int pad1:8; 110 | unsigned int pad2:16; 111 | unsigned int inL:16; 112 | unsigned int inR:16; 113 | } Ainterleave; 114 | 115 | typedef struct { 116 | unsigned int cmd:8; 117 | unsigned int pad1:24; 118 | unsigned int addr; 119 | } Aloadbuff; 120 | 121 | typedef struct { 122 | unsigned int cmd:8; 123 | unsigned int flags:8; 124 | unsigned int pad1:16; 125 | unsigned int addr; 126 | } Aenvmixer; 127 | 128 | typedef struct { 129 | unsigned int cmd:8; 130 | unsigned int flags:8; 131 | unsigned int gain:16; 132 | unsigned int dmemi:16; 133 | unsigned int dmemo:16; 134 | } Amixer; 135 | 136 | typedef struct { 137 | unsigned int cmd:8; 138 | unsigned int flags:8; 139 | unsigned int dmem2:16; 140 | unsigned int addr; 141 | } Apan; 142 | 143 | typedef struct { 144 | unsigned int cmd:8; 145 | unsigned int flags:8; 146 | unsigned int pitch:16; 147 | unsigned int addr; 148 | } Aresample; 149 | 150 | typedef struct { 151 | unsigned int cmd:8; 152 | unsigned int flags:8; 153 | unsigned int pad1:16; 154 | unsigned int addr; 155 | } Areverb; 156 | 157 | typedef struct { 158 | unsigned int cmd:8; 159 | unsigned int pad1:24; 160 | unsigned int addr; 161 | } Asavebuff; 162 | 163 | typedef struct { 164 | unsigned int cmd:8; 165 | unsigned int pad1:24; 166 | unsigned int pad2:2; 167 | unsigned int number:4; 168 | unsigned int base:24; 169 | } Asegment; 170 | 171 | typedef struct { 172 | unsigned int cmd:8; 173 | unsigned int flags:8; 174 | unsigned int dmemin:16; 175 | unsigned int dmemout:16; 176 | unsigned int count:16; 177 | } Asetbuff; 178 | 179 | typedef struct { 180 | unsigned int cmd:8; 181 | unsigned int flags:8; 182 | unsigned int vol:16; 183 | unsigned int voltgt:16; 184 | unsigned int volrate:16; 185 | } Asetvol; 186 | 187 | typedef struct { 188 | unsigned int cmd:8; 189 | unsigned int pad1:8; 190 | unsigned int dmemin:16; 191 | unsigned int dmemout:16; 192 | unsigned int count:16; 193 | } Admemmove; 194 | 195 | typedef struct { 196 | unsigned int cmd:8; 197 | unsigned int pad1:8; 198 | unsigned int count:16; 199 | unsigned int addr; 200 | } Aloadadpcm; 201 | 202 | typedef struct { 203 | unsigned int cmd:8; 204 | unsigned int pad1:8; 205 | unsigned int pad2:16; 206 | unsigned int addr; 207 | } Asetloop; 208 | 209 | /* 210 | * Generic Acmd Packet 211 | */ 212 | 213 | typedef struct { 214 | unsigned int w0; 215 | unsigned int w1; 216 | } Awords; 217 | 218 | typedef union { 219 | Awords words; 220 | Aadpcm adpcm; 221 | Apolef polef; 222 | Aclearbuff clearbuff; 223 | Aenvelope envelope; 224 | Ainterleave interleave; 225 | Aloadbuff loadbuff; 226 | Aenvmixer envmixer; 227 | Aresample resample; 228 | Areverb reverb; 229 | Asavebuff savebuff; 230 | Asegment segment; 231 | Asetbuff setbuff; 232 | Asetvol setvol; 233 | Admemmove dmemmove; 234 | Aloadadpcm loadadpcm; 235 | Amixer mixer; 236 | Asetloop setloop; 237 | long long int force_union_align; /* dummy, force alignment */ 238 | } Acmd; 239 | 240 | /* 241 | * ADPCM State 242 | */ 243 | #define ADPCMVSIZE 8 244 | #define ADPCMFSIZE 16 245 | typedef short ADPCM_STATE[ADPCMFSIZE]; 246 | 247 | /* 248 | * Pole filter state 249 | */ 250 | typedef short POLEF_STATE[4]; 251 | 252 | /* 253 | * Resampler state 254 | */ 255 | typedef short RESAMPLE_STATE[16]; 256 | 257 | /* 258 | * Resampler constants 259 | */ 260 | #define UNITY_PITCH 0x8000 261 | #define MAX_RATIO 1.99996 /* within .03 cents of +1 octave */ 262 | 263 | /* 264 | * Enveloper/Mixer state 265 | */ 266 | typedef short ENVMIX_STATE[40]; 267 | 268 | /* 269 | * Macros to assemble the audio command list 270 | */ 271 | 272 | #define aADPCMdec(pkt, f, s) \ 273 | { \ 274 | Acmd *_a = (Acmd *)pkt; \ 275 | \ 276 | _a->words.w0 = _SHIFTL(A_ADPCM, 24, 8) | _SHIFTL(f, 16, 8); \ 277 | _a->words.w1 = (unsigned int)(s); \ 278 | } 279 | 280 | #define aPoleFilter(pkt, f, g, s) \ 281 | { \ 282 | Acmd *_a = (Acmd *)pkt; \ 283 | \ 284 | _a->words.w0 = (_SHIFTL(A_POLEF, 24, 8) | _SHIFTL(f, 16, 8) | \ 285 | _SHIFTL(g, 0, 16)); \ 286 | _a->words.w1 = (unsigned int)(s); \ 287 | } 288 | 289 | #define aClearBuffer(pkt, d, c) \ 290 | { \ 291 | Acmd *_a = (Acmd *)pkt; \ 292 | \ 293 | _a->words.w0 = _SHIFTL(A_CLEARBUFF, 24, 8) | _SHIFTL(d, 0, 24); \ 294 | _a->words.w1 = (unsigned int)(c); \ 295 | } 296 | 297 | #define aEnvMixer(pkt, f, s) \ 298 | { \ 299 | Acmd *_a = (Acmd *)pkt; \ 300 | \ 301 | _a->words.w0 = _SHIFTL(A_ENVMIXER, 24, 8) | _SHIFTL(f, 16, 8); \ 302 | _a->words.w1 = (unsigned int)(s); \ 303 | } 304 | 305 | #define aInterleave(pkt, l, r) \ 306 | { \ 307 | Acmd *_a = (Acmd *)pkt; \ 308 | \ 309 | _a->words.w0 = _SHIFTL(A_INTERLEAVE, 24, 8); \ 310 | _a->words.w1 = _SHIFTL(l, 16, 16) | _SHIFTL(r, 0, 16); \ 311 | } 312 | 313 | #define aLoadBuffer(pkt, s) \ 314 | { \ 315 | Acmd *_a = (Acmd *)pkt; \ 316 | \ 317 | _a->words.w0 = _SHIFTL(A_LOADBUFF, 24, 8); \ 318 | _a->words.w1 = (unsigned int)(s); \ 319 | } 320 | 321 | #define aMix(pkt, f, g, i, o) \ 322 | { \ 323 | Acmd *_a = (Acmd *)pkt; \ 324 | \ 325 | _a->words.w0 = (_SHIFTL(A_MIXER, 24, 8) | _SHIFTL(f, 16, 8) | \ 326 | _SHIFTL(g, 0, 16)); \ 327 | _a->words.w1 = _SHIFTL(i,16, 16) | _SHIFTL(o, 0, 16); \ 328 | } 329 | 330 | #define aPan(pkt, f, d, s) \ 331 | { \ 332 | Acmd *_a = (Acmd *)pkt; \ 333 | \ 334 | _a->words.w0 = (_SHIFTL(A_PAN, 24, 8) | _SHIFTL(f, 16, 8) | \ 335 | _SHIFTL(d, 0, 16)); \ 336 | _a->words.w1 = (unsigned int)(s); \ 337 | } 338 | 339 | #define aResample(pkt, f, p, s) \ 340 | { \ 341 | Acmd *_a = (Acmd *)pkt; \ 342 | \ 343 | _a->words.w0 = (_SHIFTL(A_RESAMPLE, 24, 8) | _SHIFTL(f, 16, 8) |\ 344 | _SHIFTL(p, 0, 16)); \ 345 | _a->words.w1 = (unsigned int)(s); \ 346 | } 347 | 348 | #define aSaveBuffer(pkt, s) \ 349 | { \ 350 | Acmd *_a = (Acmd *)pkt; \ 351 | \ 352 | _a->words.w0 = _SHIFTL(A_SAVEBUFF, 24, 8); \ 353 | _a->words.w1 = (unsigned int)(s); \ 354 | } 355 | 356 | #define aSegment(pkt, s, b) \ 357 | { \ 358 | Acmd *_a = (Acmd *)pkt; \ 359 | \ 360 | _a->words.w0 = _SHIFTL(A_SEGMENT, 24, 8); \ 361 | _a->words.w1 = _SHIFTL(s, 24, 8) | _SHIFTL(b, 0, 24); \ 362 | } 363 | 364 | #define aSetBuffer(pkt, f, i, o, c) \ 365 | { \ 366 | Acmd *_a = (Acmd *)pkt; \ 367 | \ 368 | _a->words.w0 = (_SHIFTL(A_SETBUFF, 24, 8) | _SHIFTL(f, 16, 8) | \ 369 | _SHIFTL(i, 0, 16)); \ 370 | _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ 371 | } 372 | 373 | #define aSetVolume(pkt, f, v, t, r) \ 374 | { \ 375 | Acmd *_a = (Acmd *)pkt; \ 376 | \ 377 | _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ 378 | _SHIFTL(v, 0, 16)); \ 379 | _a->words.w1 = _SHIFTL(t, 16, 16) | _SHIFTL(r, 0, 16); \ 380 | } 381 | 382 | #define aSetLoop(pkt, a) \ 383 | { \ 384 | Acmd *_a = (Acmd *)pkt; \ 385 | _a->words.w0 = _SHIFTL(A_SETLOOP, 24, 8); \ 386 | _a->words.w1 = (unsigned int)(a); \ 387 | } 388 | 389 | #define aDMEMMove(pkt, i, o, c) \ 390 | { \ 391 | Acmd *_a = (Acmd *)pkt; \ 392 | \ 393 | _a->words.w0 = _SHIFTL(A_DMEMMOVE, 24, 8) | _SHIFTL(i, 0, 24); \ 394 | _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ 395 | } 396 | 397 | #define aLoadADPCM(pkt, c, d) \ 398 | { \ 399 | Acmd *_a = (Acmd *)pkt; \ 400 | \ 401 | _a->words.w0 = _SHIFTL(A_LOADADPCM, 24, 8) | _SHIFTL(c, 0, 24); \ 402 | _a->words.w1 = (unsigned int) d; \ 403 | } 404 | 405 | /* 406 | * -------------------------------------------------------------------- 407 | * The below commands are seemingly declared manually and used for the 408 | * sound driver. 409 | * -------------------------------------------------------------------- 410 | */ 411 | 412 | // This is a version of aSetAudio which takes a single 32-bit parameter 413 | // instead of two 16-bit ones. According to AziAudio, it is used to set 414 | // ramping values when neither bit 4 nor bit 8 is set in the flags parameter. 415 | 416 | #define aSetVolume32(pkt, f, v, tr) \ 417 | { \ 418 | Acmd *_a = (Acmd *)pkt; \ 419 | \ 420 | _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ 421 | _SHIFTL(v, 0, 16)); \ 422 | _a->words.w1 = (unsigned int)(tr); \ 423 | } 424 | 425 | // Like aSetBuffer, expect that the order of operands to the w1 bitor is 426 | // swapped. This is needed for the code to match... (In fact, it's almost 427 | // fine to redefine aSetBuffer itself this way, but there's a single function 428 | // whose bitor then get its order of operands messed up.) 429 | 430 | #define aSetBuffer2(pkt, f, i, o, c) \ 431 | { \ 432 | Acmd *_a = (Acmd *)pkt; \ 433 | \ 434 | _a->words.w0 = (_SHIFTL(A_SETBUFF, 24, 8) | _SHIFTL(f, 16, 8) | \ 435 | _SHIFTL(i, 0, 16)); \ 436 | _a->words.w1 = _SHIFTL(c, 0, 16) | _SHIFTL(o, 16, 16); \ 437 | } 438 | 439 | #endif /* _LANGUAGE_C */ 440 | 441 | #endif /* !_ABI_H_ */ 442 | 443 | 444 | 445 | -------------------------------------------------------------------------------- /include/PR/gu.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_GU_H_ 2 | #define _ULTRA64_GU_H_ 3 | 4 | #define GU_PI 3.1415926 5 | /* Functions */ 6 | 7 | void guPerspectiveF(float mf[4][4], u16 *perspNorm, float fovy, float aspect, 8 | float near, float far, float scale); 9 | void guPerspective(Mtx *m, u16 *perspNorm, float fovy, float aspect, float near, 10 | float far, float scale); 11 | void guOrtho(Mtx *m, float left, float right, float bottom, float top, 12 | float near, float far, float scale); 13 | void guTranslate(Mtx *m, float x, float y, float z); 14 | void guRotate(Mtx *m, float a, float x, float y, float z); 15 | void guScale(Mtx *m, float x, float y, float z); 16 | void guMtxF2L(float mf[4][4], Mtx *m); 17 | void guMtxIdent(Mtx *m); 18 | void guMtxIdentF(float mf[4][4]); 19 | void guMtxL2F(float mf[4][4], Mtx *m); 20 | void guNormalize(float *, float *, float *); 21 | 22 | /* Used only in Fast3DEX2 */ 23 | void guLookAtReflect (Mtx *m, LookAt *l, float xEye, float yEye, float zEye, 24 | float xAt, float yAt, float zAt, 25 | float xUp, float yUp, float zUp); 26 | #endif 27 | -------------------------------------------------------------------------------- /include/PR/libaudio.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_LIBAUDIO_H_ 2 | #define _ULTRA64_LIBAUDIO_H_ 3 | 4 | typedef struct 5 | { 6 | s32 order; 7 | s32 npredictors; 8 | s16 book[1]; // variable size, 8-byte aligned 9 | } ALADPCMBook; 10 | 11 | typedef struct 12 | { 13 | u8 *offset; 14 | s32 len; 15 | } ALSeqData; 16 | 17 | typedef struct 18 | { 19 | s16 revision; 20 | s16 seqCount; 21 | ALSeqData seqArray[1]; 22 | } ALSeqFile; 23 | 24 | void alSeqFileNew(ALSeqFile *f, u8 *base); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/PR/libultra.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBULTRA_H 2 | #define _LIBULTRA_H 3 | 4 | #define TV_TYPE_NTSC 1 5 | #define TV_TYPE_PAL 0 6 | #define TV_TYPE_MPAL 2 7 | 8 | #define RESET_TYPE_COLD_RESET 0 9 | #define RESET_TYPE_NMI 1 10 | #define RESET_TYPE_BOOT_DISK 2 11 | 12 | extern u32 osTvType; 13 | extern u32 osRomBase; 14 | extern u32 osResetType; 15 | extern u8 osAppNmiBuffer[64]; 16 | 17 | #endif /* _LIBULTRA_H */ 18 | -------------------------------------------------------------------------------- /include/PR/mbi.h: -------------------------------------------------------------------------------- 1 | #ifndef _MBI_H_ 2 | #define _MBI_H_ 3 | 4 | /************************************************************************** 5 | * * 6 | * Copyright (C) 1994, Silicon Graphics, Inc. * 7 | * * 8 | * These coded instructions, statements, and computer programs contain * 9 | * unpublished proprietary information of Silicon Graphics, Inc., and * 10 | * are protected by Federal copyright law. They may not be disclosed * 11 | * to third parties or copied or duplicated in any form, in whole or * 12 | * in part, without the prior written consent of Silicon Graphics, Inc. * 13 | * * 14 | **************************************************************************/ 15 | 16 | /************************************************************************** 17 | * 18 | * $Revision: 1.136 $ 19 | * $Date: 1999/01/05 13:04:00 $ 20 | * $Source: /hosts/gate3/exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/mbi.h,v $ 21 | * 22 | **************************************************************************/ 23 | 24 | /* 25 | * Header file for the Media Binary Interface 26 | * 27 | * NOTE: This file is included by the RSP microcode, so any C-specific 28 | * constructs must be bracketed by #ifdef _LANGUAGE_C 29 | * 30 | */ 31 | 32 | 33 | /* 34 | * the SHIFT macros are used to build display list commands, inserting 35 | * bit-fields into a 32-bit word. They take a value, a shift amount, 36 | * and a width. 37 | * 38 | * For the left shift, the lower bits of the value are masked, 39 | * then shifted left. 40 | * 41 | * For the right shift, the value is shifted right, then the lower bits 42 | * are masked. 43 | * 44 | * (NOTE: _SHIFTL(v, 0, 32) won't work, just use an assignment) 45 | * 46 | */ 47 | #define _SHIFTL(v, s, w) \ 48 | ((unsigned int) (((unsigned int)(v) & ((0x01 << (w)) - 1)) << (s))) 49 | #define _SHIFTR(v, s, w) \ 50 | ((unsigned int)(((unsigned int)(v) >> (s)) & ((0x01 << (w)) - 1))) 51 | 52 | #define _SHIFT _SHIFTL /* old, for compatibility only */ 53 | 54 | #define G_ON (1) 55 | #define G_OFF (0) 56 | 57 | /************************************************************************** 58 | * 59 | * Graphics Binary Interface 60 | * 61 | **************************************************************************/ 62 | 63 | #ifdef F3D_OLD 64 | #include 65 | #else 66 | #include 67 | #endif 68 | 69 | /************************************************************************** 70 | * 71 | * Audio Binary Interface 72 | * 73 | **************************************************************************/ 74 | 75 | #include 76 | 77 | /************************************************************************** 78 | * 79 | * Task list 80 | * 81 | **************************************************************************/ 82 | 83 | #define M_GFXTASK 1 84 | #define M_AUDTASK 2 85 | #define M_VIDTASK 3 86 | #define M_HVQTASK 6 87 | #define M_HVQMTASK 7 88 | 89 | /************************************************************************** 90 | * 91 | * Segment macros and definitions 92 | * 93 | **************************************************************************/ 94 | 95 | #define NUM_SEGMENTS (16) 96 | #define SEGMENT_OFFSET(a) ((unsigned int)(a) & 0x00ffffff) 97 | #define SEGMENT_NUMBER(a) (((unsigned int)(a) << 4) >> 28) 98 | #define SEGMENT_ADDR(num, off) (((num) << 24) + (off)) 99 | 100 | #ifndef NULL 101 | #define NULL 0 102 | #endif 103 | 104 | #endif /* !_MBI_H_ */ 105 | -------------------------------------------------------------------------------- /include/PR/os_ai.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_ai.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_ai.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:04 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_AI_H_ 31 | #define _OS_AI_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | 48 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 49 | 50 | /************************************************************************** 51 | * 52 | * Global definitions 53 | * 54 | */ 55 | 56 | 57 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 58 | 59 | /************************************************************************** 60 | * 61 | * Macro definitions 62 | * 63 | */ 64 | 65 | 66 | /************************************************************************** 67 | * 68 | * Extern variables 69 | * 70 | */ 71 | 72 | 73 | /************************************************************************** 74 | * 75 | * Function prototypes 76 | * 77 | */ 78 | 79 | /* Audio interface (Ai) */ 80 | extern u32 osAiGetStatus(void); 81 | extern u32 osAiGetLength(void); 82 | extern s32 osAiSetFrequency(u32); 83 | extern s32 osAiSetNextBuffer(void *, u32); 84 | 85 | 86 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 87 | 88 | #ifdef _LANGUAGE_C_PLUS_PLUS 89 | } 90 | #endif 91 | 92 | #endif /* !_OS_AI_H_ */ 93 | -------------------------------------------------------------------------------- /include/PR/os_cache.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_cache.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_cache.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:04 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_CACHE_H_ 31 | #define _OS_CACHE_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | 48 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 49 | 50 | /************************************************************************** 51 | * 52 | * Global definitions 53 | * 54 | */ 55 | 56 | 57 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 58 | 59 | /************************************************************************** 60 | * 61 | * Macro definitions 62 | * 63 | */ 64 | 65 | #define OS_DCACHE_ROUNDUP_ADDR(x) (void *)(((((u32)(x)+0xf)/0x10)*0x10)) 66 | #define OS_DCACHE_ROUNDUP_SIZE(x) (u32)(((((u32)(x)+0xf)/0x10)*0x10)) 67 | 68 | 69 | /************************************************************************** 70 | * 71 | * Extern variables 72 | * 73 | */ 74 | 75 | 76 | /************************************************************************** 77 | * 78 | * Function prototypes 79 | * 80 | */ 81 | 82 | /* Cache operations and macros */ 83 | 84 | extern void osInvalDCache(void *, s32); 85 | extern void osInvalICache(void *, s32); 86 | extern void osWritebackDCache(void *, s32); 87 | extern void osWritebackDCacheAll(void); 88 | 89 | 90 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 91 | 92 | #ifdef _LANGUAGE_C_PLUS_PLUS 93 | } 94 | #endif 95 | 96 | #endif /* !_OS_CACHE_H_ */ 97 | -------------------------------------------------------------------------------- /include/PR/os_cont.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_cont.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_cont.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:05 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_CONT_H_ 31 | #define _OS_CONT_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include "os_message.h" 39 | 40 | 41 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 42 | 43 | /************************************************************************** 44 | * 45 | * Type definitions 46 | * 47 | */ 48 | 49 | /* 50 | * Structure for controllers 51 | */ 52 | 53 | typedef struct { 54 | u16 type; /* Controller Type */ 55 | u8 status; /* Controller status */ 56 | u8 errno; 57 | }OSContStatus; 58 | 59 | typedef struct { 60 | u16 button; 61 | s8 stick_x; /* -80 <= stick_x <= 80 */ 62 | s8 stick_y; /* -80 <= stick_y <= 80 */ 63 | u8 errno; 64 | } OSContPad; 65 | 66 | typedef struct { 67 | void *address; /* Ram pad Address: 11 bits */ 68 | u8 databuffer[32]; /* address of the data buffer */ 69 | u8 addressCrc; /* CRC code for address */ 70 | u8 dataCrc; /* CRC code for data */ 71 | u8 errno; 72 | } OSContRamIo; 73 | 74 | 75 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 76 | 77 | /************************************************************************** 78 | * 79 | * Global definitions 80 | * 81 | */ 82 | 83 | /* 84 | * Controllers number 85 | */ 86 | 87 | #ifndef _HW_VERSION_1 88 | #define MAXCONTROLLERS 4 89 | #else 90 | #define MAXCONTROLLERS 6 91 | #endif 92 | 93 | /* controller errors */ 94 | #define CONT_NO_RESPONSE_ERROR 0x8 95 | #define CONT_OVERRUN_ERROR 0x4 96 | #ifdef _HW_VERSION_1 97 | #define CONT_FRAME_ERROR 0x2 98 | #define CONT_COLLISION_ERROR 0x1 99 | #endif 100 | 101 | /* Controller type */ 102 | 103 | #define CONT_ABSOLUTE 0x0001 104 | #define CONT_RELATIVE 0x0002 105 | #define CONT_JOYPORT 0x0004 106 | #define CONT_EEPROM 0x8000 107 | #define CONT_EEP16K 0x4000 108 | #define CONT_TYPE_MASK 0x1f07 109 | #define CONT_TYPE_NORMAL 0x0005 110 | #define CONT_TYPE_MOUSE 0x0002 111 | #define CONT_TYPE_VOICE 0x0100 112 | 113 | /* Controller status */ 114 | 115 | #define CONT_CARD_ON 0x01 116 | #define CONT_CARD_PULL 0x02 117 | #define CONT_ADDR_CRC_ER 0x04 118 | #define CONT_EEPROM_BUSY 0x80 119 | 120 | /* Buttons */ 121 | 122 | #define CONT_A 0x8000 123 | #define CONT_B 0x4000 124 | #define CONT_G 0x2000 125 | #define CONT_START 0x1000 126 | #define CONT_UP 0x0800 127 | #define CONT_DOWN 0x0400 128 | #define CONT_LEFT 0x0200 129 | #define CONT_RIGHT 0x0100 130 | #define CONT_L 0x0020 131 | #define CONT_R 0x0010 132 | #define CONT_E 0x0008 133 | #define CONT_D 0x0004 134 | #define CONT_C 0x0002 135 | #define CONT_F 0x0001 136 | 137 | /* Nintendo's official button names */ 138 | 139 | #define A_BUTTON CONT_A 140 | #define B_BUTTON CONT_B 141 | #define L_TRIG CONT_L 142 | #define R_TRIG CONT_R 143 | #define Z_TRIG CONT_G 144 | #define START_BUTTON CONT_START 145 | #define U_JPAD CONT_UP 146 | #define L_JPAD CONT_LEFT 147 | #define R_JPAD CONT_RIGHT 148 | #define D_JPAD CONT_DOWN 149 | #define U_CBUTTONS CONT_E 150 | #define L_CBUTTONS CONT_C 151 | #define R_CBUTTONS CONT_F 152 | #define D_CBUTTONS CONT_D 153 | 154 | /* Controller error number */ 155 | 156 | #define CONT_ERR_NO_CONTROLLER PFS_ERR_NOPACK /* 1 */ 157 | #define CONT_ERR_CONTRFAIL CONT_OVERRUN_ERROR /* 4 */ 158 | #define CONT_ERR_INVALID PFS_ERR_INVALID /* 5 */ 159 | #define CONT_ERR_DEVICE PFS_ERR_DEVICE /* 11 */ 160 | #define CONT_ERR_NOT_READY 12 161 | #define CONT_ERR_VOICE_MEMORY 13 162 | #define CONT_ERR_VOICE_WORD 14 163 | #define CONT_ERR_VOICE_NO_RESPONSE 15 164 | 165 | 166 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 167 | 168 | /************************************************************************** 169 | * 170 | * Macro definitions 171 | * 172 | */ 173 | 174 | 175 | /************************************************************************** 176 | * 177 | * Extern variables 178 | * 179 | */ 180 | 181 | 182 | /************************************************************************** 183 | * 184 | * Function prototypes 185 | * 186 | */ 187 | 188 | /* Controller interface */ 189 | 190 | extern s32 osContInit(OSMesgQueue *, u8 *, OSContStatus *); 191 | extern s32 osContReset(OSMesgQueue *, OSContStatus *); 192 | extern s32 osContStartQuery(OSMesgQueue *); 193 | extern s32 osContStartReadData(OSMesgQueue *); 194 | #ifndef _HW_VERSION_1 195 | extern s32 osContSetCh(u8); 196 | #endif 197 | extern void osContGetQuery(OSContStatus *); 198 | extern void osContGetReadData(OSContPad *); 199 | 200 | 201 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 202 | 203 | #ifdef _LANGUAGE_C_PLUS_PLUS 204 | } 205 | #endif 206 | 207 | #endif /* !_OS_CONT_H_ */ 208 | -------------------------------------------------------------------------------- /include/PR/os_eeprom.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_eeprom.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_eeprom.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:06 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_EEPROM_H_ 31 | #define _OS_EEPROM_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include "os_message.h" 39 | 40 | 41 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 42 | 43 | /************************************************************************** 44 | * 45 | * Type definitions 46 | * 47 | */ 48 | 49 | 50 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 51 | 52 | /************************************************************************** 53 | * 54 | * Global definitions 55 | * 56 | */ 57 | 58 | /* EEPROM TYPE */ 59 | 60 | #define EEPROM_TYPE_4K 0x01 61 | #define EEPROM_TYPE_16K 0x02 62 | 63 | /* definition for EEPROM */ 64 | 65 | #define EEPROM_MAXBLOCKS 64 66 | #define EEP16K_MAXBLOCKS 256 67 | #define EEPROM_BLOCK_SIZE 8 68 | 69 | 70 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 71 | 72 | /************************************************************************** 73 | * 74 | * Macro definitions 75 | * 76 | */ 77 | 78 | 79 | /************************************************************************** 80 | * 81 | * Extern variables 82 | * 83 | */ 84 | 85 | 86 | /************************************************************************** 87 | * 88 | * Function prototypes 89 | * 90 | */ 91 | 92 | /* EEPROM interface */ 93 | 94 | extern s32 osEepromProbe(OSMesgQueue *); 95 | extern s32 osEepromRead(OSMesgQueue *, u8, u8 *); 96 | extern s32 osEepromWrite(OSMesgQueue *, u8, u8 *); 97 | extern s32 osEepromLongRead(OSMesgQueue *, u8, u8 *, int); 98 | extern s32 osEepromLongWrite(OSMesgQueue *, u8, u8 *, int); 99 | 100 | 101 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 102 | 103 | #ifdef _LANGUAGE_C_PLUS_PLUS 104 | } 105 | #endif 106 | 107 | #endif /* !_OS_EEPROM_H_ */ 108 | -------------------------------------------------------------------------------- /include/PR/os_exception.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_exception.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_exception.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:07 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_EXCEPTION_H_ 31 | #define _OS_EXCEPTION_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | typedef u32 OSIntMask; 48 | typedef u32 OSHWIntr; 49 | 50 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 51 | 52 | /************************************************************************** 53 | * 54 | * Global definitions 55 | * 56 | */ 57 | 58 | /* Flags for debugging purpose */ 59 | 60 | #define OS_FLAG_CPU_BREAK 1 /* Break exception has occurred */ 61 | #define OS_FLAG_FAULT 2 /* CPU fault has occurred */ 62 | 63 | /* Interrupt masks */ 64 | 65 | #define OS_IM_NONE 0x00000001 66 | #define OS_IM_SW1 0x00000501 67 | #define OS_IM_SW2 0x00000601 68 | #define OS_IM_CART 0x00000c01 69 | #define OS_IM_PRENMI 0x00001401 70 | #define OS_IM_RDBWRITE 0x00002401 71 | #define OS_IM_RDBREAD 0x00004401 72 | #define OS_IM_COUNTER 0x00008401 73 | #define OS_IM_CPU 0x0000ff01 74 | #define OS_IM_SP 0x00010401 75 | #define OS_IM_SI 0x00020401 76 | #define OS_IM_AI 0x00040401 77 | #define OS_IM_VI 0x00080401 78 | #define OS_IM_PI 0x00100401 79 | #define OS_IM_DP 0x00200401 80 | #define OS_IM_ALL 0x003fff01 81 | #define RCP_IMASK 0x003f0000 82 | #define RCP_IMASKSHIFT 16 83 | 84 | 85 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 86 | 87 | /************************************************************************** 88 | * 89 | * Macro definitions 90 | * 91 | */ 92 | 93 | 94 | /************************************************************************** 95 | * 96 | * Extern variables 97 | * 98 | */ 99 | 100 | 101 | /************************************************************************** 102 | * 103 | * Function prototypes 104 | * 105 | */ 106 | 107 | /* Interrupt operations */ 108 | 109 | extern OSIntMask osGetIntMask(void); 110 | extern OSIntMask osSetIntMask(OSIntMask); 111 | 112 | 113 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 114 | 115 | #ifdef _LANGUAGE_C_PLUS_PLUS 116 | } 117 | #endif 118 | 119 | #endif /* !_OS_EXCEPTION_H_ */ 120 | -------------------------------------------------------------------------------- /include/PR/os_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_OS_INTERNAL_H_ 2 | #define _ULTRA64_OS_INTERNAL_H_ 3 | 4 | /* Internal functions used by the operating system */ 5 | /* Do not include this header in application code */ 6 | 7 | /* Variables */ 8 | 9 | //extern u64 osClockRate; 10 | 11 | /* Functions */ 12 | 13 | /*u32 __osProbeTLB(void *); 14 | u32 __osDisableInt(void); 15 | void __osRestoreInt(u32);*/ 16 | #endif 17 | -------------------------------------------------------------------------------- /include/PR/os_libc.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_libc.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_libc.h,v $ 26 | $Revision: 1.3 $ 27 | $Date: 1999/07/13 01:43:47 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_LIBC_H_ 31 | #define _OS_LIBC_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | 48 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 49 | 50 | /************************************************************************** 51 | * 52 | * Global definitions 53 | * 54 | */ 55 | 56 | 57 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 58 | 59 | /************************************************************************** 60 | * 61 | * Macro definitions 62 | * 63 | */ 64 | 65 | 66 | /************************************************************************** 67 | * 68 | * Extern variables 69 | * 70 | */ 71 | 72 | 73 | /************************************************************************** 74 | * 75 | * Function prototypes 76 | * 77 | */ 78 | 79 | /* byte string operations */ 80 | 81 | 82 | extern void bcopy(const void *, void *, int); 83 | extern int bcmp(const void *, const void *, int); 84 | extern void bzero(void *, int); 85 | 86 | /* Printf */ 87 | 88 | extern int sprintf(char *s, const char *fmt, ...); 89 | extern void osSyncPrintf(const char *fmt, ...); 90 | 91 | 92 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 93 | 94 | #ifdef _LANGUAGE_C_PLUS_PLUS 95 | } 96 | #endif 97 | 98 | #endif /* !_OS_LIBC_H_ */ 99 | -------------------------------------------------------------------------------- /include/PR/os_message.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_message.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_message.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:15 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_MESSAGE_H_ 31 | #define _OS_MESSAGE_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | typedef u32 OSEvent; 48 | 49 | /* 50 | * Structure for message 51 | */ 52 | typedef void * OSMesg; 53 | 54 | /* 55 | * Structure for message queue 56 | */ 57 | typedef struct OSMesgQueue_s { 58 | OSThread *mtqueue; /* Queue to store threads blocked 59 | on empty mailboxes (receive) */ 60 | OSThread *fullqueue; /* Queue to store threads blocked 61 | on full mailboxes (send) */ 62 | s32 validCount; /* Contains number of valid message */ 63 | s32 first; /* Points to first valid message */ 64 | s32 msgCount; /* Contains total # of messages */ 65 | OSMesg *msg; /* Points to message buffer array */ 66 | } OSMesgQueue; 67 | 68 | 69 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 70 | 71 | /************************************************************************** 72 | * 73 | * Global definitions 74 | * 75 | */ 76 | 77 | /* Events */ 78 | #ifdef _FINALROM 79 | #define OS_NUM_EVENTS 15 80 | #else 81 | #define OS_NUM_EVENTS 23 82 | #endif 83 | 84 | #define OS_EVENT_SW1 0 /* CPU SW1 interrupt */ 85 | #define OS_EVENT_SW2 1 /* CPU SW2 interrupt */ 86 | #define OS_EVENT_CART 2 /* Cartridge interrupt: used by rmon */ 87 | #define OS_EVENT_COUNTER 3 /* Counter int: used by VI/Timer Mgr */ 88 | #define OS_EVENT_SP 4 /* SP task done interrupt */ 89 | #define OS_EVENT_SI 5 /* SI (controller) interrupt */ 90 | #define OS_EVENT_AI 6 /* AI interrupt */ 91 | #define OS_EVENT_VI 7 /* VI interrupt: used by VI/Timer Mgr */ 92 | #define OS_EVENT_PI 8 /* PI interrupt: used by PI Manager */ 93 | #define OS_EVENT_DP 9 /* DP full sync interrupt */ 94 | #define OS_EVENT_CPU_BREAK 10 /* CPU breakpoint: used by rmon */ 95 | #define OS_EVENT_SP_BREAK 11 /* SP breakpoint: used by rmon */ 96 | #define OS_EVENT_FAULT 12 /* CPU fault event: used by rmon */ 97 | #define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */ 98 | #define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */ 99 | #ifndef _FINALROM 100 | #define OS_EVENT_RDB_READ_DONE 15 /* RDB read ok event: used by rmon */ 101 | #define OS_EVENT_RDB_LOG_DONE 16 /* read of log data complete */ 102 | #define OS_EVENT_RDB_DATA_DONE 17 /* read of hostio data complete */ 103 | #define OS_EVENT_RDB_REQ_RAMROM 18 /* host needs ramrom access */ 104 | #define OS_EVENT_RDB_FREE_RAMROM 19 /* host is done with ramrom access */ 105 | #define OS_EVENT_RDB_DBG_DONE 20 106 | #define OS_EVENT_RDB_FLUSH_PROF 21 107 | #define OS_EVENT_RDB_ACK_PROF 22 108 | #endif 109 | 110 | /* Flags to turn blocking on/off when sending/receiving message */ 111 | 112 | #define OS_MESG_NOBLOCK 0 113 | #define OS_MESG_BLOCK 1 114 | 115 | 116 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 117 | 118 | /************************************************************************** 119 | * 120 | * Macro definitions 121 | * 122 | */ 123 | 124 | /* Get count of valid messages in queue */ 125 | #define MQ_GET_COUNT(mq) ((mq)->validCount) 126 | 127 | /* Figure out if message queue is empty or full */ 128 | #define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq) == 0) 129 | #define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq) >= (mq)->msgCount) 130 | 131 | 132 | /************************************************************************** 133 | * 134 | * Extern variables 135 | * 136 | */ 137 | 138 | 139 | /************************************************************************** 140 | * 141 | * Function prototypes 142 | * 143 | */ 144 | 145 | /* Message operations */ 146 | 147 | extern void osCreateMesgQueue(OSMesgQueue *, OSMesg *, s32); 148 | extern s32 osSendMesg(OSMesgQueue *, OSMesg, s32); 149 | extern s32 osJamMesg(OSMesgQueue *, OSMesg, s32); 150 | extern s32 osRecvMesg(OSMesgQueue *, OSMesg *, s32); 151 | 152 | /* Event operations */ 153 | 154 | extern void osSetEventMesg(OSEvent, OSMesgQueue *, OSMesg); 155 | 156 | 157 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 158 | 159 | #ifdef _LANGUAGE_C_PLUS_PLUS 160 | } 161 | #endif 162 | 163 | #endif /* !_OS_MESSAGE_H_ */ 164 | -------------------------------------------------------------------------------- /include/PR/os_misc.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_OS_MISC_H_ 2 | #define _ULTRA64_OS_MISC_H_ 3 | 4 | /* Miscellaneous OS functions */ 5 | 6 | void osInitialize(void); 7 | u32 osGetCount(void); 8 | 9 | u32 osVirtualToPhysical(void *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /include/PR/os_pi.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_PI_H_ 2 | #define _ULTRA64_PI_H_ 3 | 4 | /* Ultra64 Parallel Interface */ 5 | 6 | /* Types */ 7 | 8 | typedef struct 9 | { 10 | u32 errStatus; 11 | void *dramAddr; 12 | void *C2Addr; 13 | u32 sectorSize; 14 | u32 C1ErrNum; 15 | u32 C1ErrSector[4]; 16 | } __OSBlockInfo; 17 | 18 | typedef struct 19 | { 20 | u32 cmdType; 21 | u16 transferMode; 22 | u16 blockNum; 23 | s32 sectorNum; 24 | u32 devAddr; 25 | u32 bmCtlShadow; 26 | u32 seqCtlShadow; 27 | __OSBlockInfo block[2]; 28 | } __OSTranxInfo; 29 | 30 | typedef struct OSPiHandle_s 31 | { 32 | struct OSPiHandle_s *next; 33 | u8 type; 34 | u8 latency; 35 | u8 pageSize; 36 | u8 relDuration; 37 | u8 pulse; 38 | u8 domain; 39 | u32 baseAddress; 40 | u32 speed; 41 | __OSTranxInfo transferInfo; 42 | } OSPiHandle; 43 | 44 | typedef struct 45 | { 46 | u8 type; 47 | u32 address; 48 | } OSPiInfo; 49 | 50 | typedef struct 51 | { 52 | u16 type; 53 | u8 pri; 54 | u8 status; 55 | OSMesgQueue *retQueue; 56 | } OSIoMesgHdr; 57 | 58 | typedef struct 59 | { 60 | /*0x00*/ OSIoMesgHdr hdr; 61 | /*0x08*/ void *dramAddr; 62 | /*0x0C*/ u32 devAddr; 63 | /*0x10*/ u32 size; 64 | //OSPiHandle *piHandle; //from the official definition 65 | } OSIoMesg; 66 | 67 | /* Definitions */ 68 | 69 | #define OS_READ 0 // device -> RDRAM 70 | #define OS_WRITE 1 // device <- RDRAM 71 | 72 | #define OS_MESG_PRI_NORMAL 0 73 | #define OS_MESG_PRI_HIGH 1 74 | 75 | /* Functions */ 76 | 77 | s32 osPiStartDma(OSIoMesg *mb, s32 priority, s32 direction, 78 | u32 devAddr, void *vAddr, u32 nbytes, OSMesgQueue *mq); 79 | void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, 80 | s32 cmdMsgCnt); 81 | OSMesgQueue *osPiGetCmdQueue(void); 82 | s32 osPiWriteIo(u32 devAddr, u32 data); 83 | s32 osPiReadIo(u32 devAddr, u32 *data); 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /include/PR/os_rdp.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_rdp.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_rdp.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:16 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_RDP_H_ 31 | #define _OS_RDP_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | 48 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 49 | 50 | /************************************************************************** 51 | * 52 | * Global definitions 53 | * 54 | */ 55 | 56 | 57 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 58 | 59 | /************************************************************************** 60 | * 61 | * Macro definitions 62 | * 63 | */ 64 | 65 | 66 | /************************************************************************** 67 | * 68 | * Extern variables 69 | * 70 | */ 71 | 72 | 73 | /************************************************************************** 74 | * 75 | * Function prototypes 76 | * 77 | */ 78 | 79 | /* Display processor interface (Dp) */ 80 | extern u32 osDpGetStatus(void); 81 | extern void osDpSetStatus(u32); 82 | extern void osDpGetCounters(u32 *); 83 | extern s32 osDpSetNextBuffer(void *, u64); 84 | 85 | 86 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 87 | 88 | #ifdef _LANGUAGE_C_PLUS_PLUS 89 | } 90 | #endif 91 | 92 | #endif /* !_OS_RDP_H_ */ 93 | -------------------------------------------------------------------------------- /include/PR/os_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_THREAD_H_ 2 | #define _ULTRA64_THREAD_H_ 3 | 4 | /* Recommended priorities for system threads */ 5 | #define OS_PRIORITY_MAX 255 6 | #define OS_PRIORITY_VIMGR 254 7 | #define OS_PRIORITY_RMON 250 8 | #define OS_PRIORITY_RMONSPIN 200 9 | #define OS_PRIORITY_PIMGR 150 10 | #define OS_PRIORITY_SIMGR 140 11 | #define OS_PRIORITY_APPMAX 127 12 | #define OS_PRIORITY_IDLE 0 13 | 14 | #define OS_STATE_STOPPED 1 15 | #define OS_STATE_RUNNABLE 2 16 | #define OS_STATE_RUNNING 4 17 | #define OS_STATE_WAITING 8 18 | 19 | /* Types */ 20 | 21 | typedef s32 OSPri; 22 | typedef s32 OSId; 23 | 24 | typedef union 25 | { 26 | struct {f32 f_odd; f32 f_even;} f; 27 | } __OSfp; 28 | 29 | typedef struct 30 | { 31 | /* registers */ 32 | /*0x20*/ u64 at, v0, v1, a0, a1, a2, a3; 33 | /*0x58*/ u64 t0, t1, t2, t3, t4, t5, t6, t7; 34 | /*0x98*/ u64 s0, s1, s2, s3, s4, s5, s6, s7; 35 | /*0xD8*/ u64 t8, t9, gp, sp, s8, ra; 36 | /*0x108*/ u64 lo, hi; 37 | /*0x118*/ u32 sr, pc, cause, badvaddr, rcp; 38 | /*0x12C*/ u32 fpcsr; 39 | __OSfp fp0, fp2, fp4, fp6, fp8, fp10, fp12, fp14; 40 | __OSfp fp16, fp18, fp20, fp22, fp24, fp26, fp28, fp30; 41 | } __OSThreadContext; 42 | 43 | typedef struct 44 | { 45 | u32 flag; 46 | u32 count; 47 | u64 time; 48 | } __OSThreadprofile_s; 49 | 50 | typedef struct OSThread_s 51 | { 52 | /*0x00*/ struct OSThread_s *next; 53 | /*0x04*/ OSPri priority; 54 | /*0x08*/ struct OSThread_s **queue; 55 | /*0x0C*/ struct OSThread_s *tlnext; 56 | /*0x10*/ u16 state; 57 | /*0x12*/ u16 flags; 58 | /*0x14*/ OSId id; 59 | /*0x18*/ int fp; 60 | /*0x1C*/ __OSThreadprofile_s *thprof; 61 | /*0x20*/ __OSThreadContext context; 62 | } OSThread; 63 | 64 | 65 | /* Functions */ 66 | 67 | void osCreateThread(OSThread *thread, OSId id, void (*entry)(void *), 68 | void *arg, void *sp, OSPri pri); 69 | OSId osGetThreadId(OSThread *thread); 70 | OSPri osGetThreadPri(OSThread *thread); 71 | void osSetThreadPri(OSThread *thread, OSPri pri); 72 | void osStartThread(OSThread *thread); 73 | void osStopThread(OSThread *thread); 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /include/PR/os_time.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_TIME_H_ 2 | #define _ULTRA64_TIME_H_ 3 | #include 4 | 5 | /* Types */ 6 | 7 | typedef struct OSTimer_str 8 | { 9 | struct OSTimer_str *next; 10 | struct OSTimer_str *prev; 11 | u64 interval; 12 | u64 remaining; 13 | OSMesgQueue *mq; 14 | OSMesg *msg; 15 | } OSTimer; 16 | 17 | typedef u64 OSTime; 18 | 19 | /* Functions */ 20 | 21 | OSTime osGetTime(void); 22 | void osSetTime(OSTime time); 23 | u32 osSetTimer(OSTimer *, OSTime, u64, OSMesgQueue *, OSMesg); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /include/PR/os_tlb.h: -------------------------------------------------------------------------------- 1 | 2 | /*==================================================================== 3 | * os_tlb.h 4 | * 5 | * Copyright 1995, Silicon Graphics, Inc. 6 | * All Rights Reserved. 7 | * 8 | * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, 9 | * Inc.; the contents of this file may not be disclosed to third 10 | * parties, copied or duplicated in any form, in whole or in part, 11 | * without the prior written permission of Silicon Graphics, Inc. 12 | * 13 | * RESTRICTED RIGHTS LEGEND: 14 | * Use, duplication or disclosure by the Government is subject to 15 | * restrictions as set forth in subdivision (c)(1)(ii) of the Rights 16 | * in Technical Data and Computer Software clause at DFARS 17 | * 252.227-7013, and/or in similar or successor clauses in the FAR, 18 | * DOD or NASA FAR Supplement. Unpublished - rights reserved under the 19 | * Copyright Laws of the United States. 20 | *====================================================================*/ 21 | 22 | /*---------------------------------------------------------------------* 23 | Copyright (C) 1998 Nintendo. (Originated by SGI) 24 | 25 | $RCSfile: os_tlb.h,v $ 26 | $Revision: 1.1 $ 27 | $Date: 1998/10/09 08:01:20 $ 28 | *---------------------------------------------------------------------*/ 29 | 30 | #ifndef _OS_TLB_H_ 31 | #define _OS_TLB_H_ 32 | 33 | #ifdef _LANGUAGE_C_PLUS_PLUS 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 40 | 41 | /************************************************************************** 42 | * 43 | * Type definitions 44 | * 45 | */ 46 | 47 | typedef u32 OSPageMask; 48 | 49 | 50 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 51 | 52 | /************************************************************************** 53 | * 54 | * Global definitions 55 | * 56 | */ 57 | 58 | /* 59 | * Page size argument for TLB routines 60 | */ 61 | #define OS_PM_4K 0x0000000 62 | #define OS_PM_16K 0x0006000 63 | #define OS_PM_64K 0x001e000 64 | #define OS_PM_256K 0x007e000 65 | #define OS_PM_1M 0x01fe000 66 | #define OS_PM_4M 0x07fe000 67 | #define OS_PM_16M 0x1ffe000 68 | 69 | 70 | #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) 71 | 72 | /************************************************************************** 73 | * 74 | * Macro definitions 75 | * 76 | */ 77 | 78 | 79 | /************************************************************************** 80 | * 81 | * Extern variables 82 | * 83 | */ 84 | 85 | 86 | /************************************************************************** 87 | * 88 | * Function prototypes 89 | * 90 | */ 91 | 92 | /* TLB management routines */ 93 | 94 | extern void osMapTLB(s32, OSPageMask, void *, u32, u32, s32); 95 | extern void osMapTLBRdb(void); 96 | extern void osUnmapTLB(s32); 97 | extern void osUnmapTLBAll(void); 98 | extern void osSetTLBASID(s32); 99 | 100 | 101 | #endif /* defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) */ 102 | 103 | #ifdef _LANGUAGE_C_PLUS_PLUS 104 | } 105 | #endif 106 | 107 | #endif /* !_OS_TLB_H_ */ 108 | -------------------------------------------------------------------------------- /include/PR/os_vi.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_VI_H_ 2 | #define _ULTRA64_VI_H_ 3 | 4 | /* Ultra64 Video Interface */ 5 | 6 | 7 | /* Special Features */ 8 | #define OS_VI_GAMMA_ON 0x0001 9 | #define OS_VI_GAMMA_OFF 0x0002 10 | #define OS_VI_GAMMA_DITHER_ON 0x0004 11 | #define OS_VI_GAMMA_DITHER_OFF 0x0008 12 | #define OS_VI_DIVOT_ON 0x0010 13 | #define OS_VI_DIVOT_OFF 0x0020 14 | #define OS_VI_DITHER_FILTER_ON 0x0040 15 | #define OS_VI_DITHER_FILTER_OFF 0x0080 16 | 17 | #define OS_VI_GAMMA 0x08 18 | #define OS_VI_GAMMA_DITHER 0x04 19 | #define OS_VI_DIVOT 0x10 20 | #define OS_VI_DITHER_FILTER 0x10000 21 | #define OS_VI_UNK200 0x200 22 | #define OS_VI_UNK100 0x100 23 | 24 | 25 | /* Types */ 26 | 27 | typedef struct 28 | { 29 | u32 ctrl; 30 | u32 width; 31 | u32 burst; 32 | u32 vSync; 33 | u32 hSync; 34 | u32 leap; 35 | u32 hStart; 36 | u32 xScale; 37 | u32 vCurrent; 38 | } OSViCommonRegs; 39 | 40 | typedef struct 41 | { 42 | u32 origin; 43 | u32 yScale; 44 | u32 vStart; 45 | u32 vBurst; 46 | u32 vIntr; 47 | } OSViFieldRegs; 48 | 49 | typedef struct 50 | { 51 | u8 type; 52 | OSViCommonRegs comRegs; 53 | OSViFieldRegs fldRegs[2]; 54 | } OSViMode; 55 | 56 | typedef struct 57 | { 58 | /* 0x00 */ u16 unk00; //some kind of flags. swap buffer sets to 0x10 59 | /* 0x02 */ u16 retraceCount; 60 | /* 0x04 */ void* buffer; 61 | /* 0x08 */ OSViMode *unk08; 62 | /* 0x0c */ u32 features; 63 | /* 0x10 */ OSMesgQueue *mq; 64 | /* 0x14 */ OSMesg *msg; 65 | /* 0x18 */ u32 unk18; 66 | /* 0x1c */ u32 unk1c; 67 | /* 0x20 */ u32 unk20; 68 | /* 0x24 */ f32 unk24; 69 | /* 0x28 */ u16 unk28; 70 | /* 0x2c */ u32 unk2c; 71 | } OSViContext; 72 | 73 | void osCreateViManager(OSPri pri); 74 | void osViSetMode(OSViMode *mode); 75 | void osViBlack(u8 active); 76 | void osViSetSpecialFeatures(u32 func); 77 | void osViSwapBuffer(void *vaddr); 78 | 79 | 80 | #define OS_VI_NTSC_LPN1 0 /* NTSC */ 81 | #define OS_VI_NTSC_LPF1 1 82 | #define OS_VI_NTSC_LAN1 2 83 | #define OS_VI_NTSC_LAF1 3 84 | #define OS_VI_NTSC_LPN2 4 85 | #define OS_VI_NTSC_LPF2 5 86 | #define OS_VI_NTSC_LAN2 6 87 | #define OS_VI_NTSC_LAF2 7 88 | #define OS_VI_NTSC_HPN1 8 89 | #define OS_VI_NTSC_HPF1 9 90 | #define OS_VI_NTSC_HAN1 10 91 | #define OS_VI_NTSC_HAF1 11 92 | #define OS_VI_NTSC_HPN2 12 93 | #define OS_VI_NTSC_HPF2 13 94 | 95 | #define OS_VI_PAL_LPN1 14 /* PAL */ 96 | #define OS_VI_PAL_LPF1 15 97 | #define OS_VI_PAL_LAN1 16 98 | #define OS_VI_PAL_LAF1 17 99 | #define OS_VI_PAL_LPN2 18 100 | #define OS_VI_PAL_LPF2 19 101 | #define OS_VI_PAL_LAN2 20 102 | #define OS_VI_PAL_LAF2 21 103 | #define OS_VI_PAL_HPN1 22 104 | #define OS_VI_PAL_HPF1 23 105 | #define OS_VI_PAL_HAN1 24 106 | #define OS_VI_PAL_HAF1 25 107 | #define OS_VI_PAL_HPN2 26 108 | #define OS_VI_PAL_HPF2 27 109 | 110 | extern OSViMode osViModeTable[]; /* Global VI mode table */ 111 | 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /include/PR/sptask.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_SPTASK_H_ 2 | #define _ULTRA64_SPTASK_H_ 3 | 4 | /* Task Types */ 5 | #define M_GFXTASK 1 6 | #define M_AUDTASK 2 7 | #define M_VIDTASK 3 8 | #define M_HVQTASK 6 9 | #define M_HVQMTASK 7 10 | 11 | //gGfxSPTaskYieldBuffer has to be changed for this too 12 | #if (defined(F3DEX_GBI) || defined(F3DLP_GBI) || defined(F3DEX_GBI_2)) 13 | #define OS_YIELD_DATA_SIZE 0xc00 14 | #else 15 | #define OS_YIELD_DATA_SIZE 0x900 16 | #endif 17 | #define OS_YIELD_AUDIO_SIZE 0x400 18 | 19 | /* Flags */ 20 | #define M_TASK_FLAG0 1 21 | #define M_TASK_FLAG1 2 22 | 23 | /* SpStatus */ 24 | #define SPSTATUS_CLEAR_HALT 0x00000001 25 | #define SPSTATUS_SET_HALT 0x00000002 26 | #define SPSTATUS_CLEAR_BROKE 0x00000004 27 | #define SPSTATUS_CLEAR_INTR 0x00000008 28 | #define SPSTATUS_SET_INTR 0x00000010 29 | #define SPSTATUS_CLEAR_SSTEP 0x00000020 30 | #define SPSTATUS_SET_SSTEP 0x00000040 31 | #define SPSTATUS_CLEAR_INTR_ON_BREAK 0x00000080 32 | #define SPSTATUS_SET_INTR_ON_BREAK 0x00000100 33 | #define SPSTATUS_CLEAR_SIGNAL0 0x00000200 34 | #define SPSTATUS_SET_SIGNAL0 0x00000400 35 | #define SPSTATUS_CLEAR_SIGNAL1 0x00000800 36 | #define SPSTATUS_SET_SIGNAL1 0x00001000 37 | #define SPSTATUS_CLEAR_SIGNAL2 0x00002000 38 | #define SPSTATUS_SET_SIGNAL2 0x00004000 39 | #define SPSTATUS_CLEAR_SIGNAL3 0x00008000 40 | #define SPSTATUS_SET_SIGNAL3 0x00010000 41 | #define SPSTATUS_CLEAR_SIGNAL4 0x00020000 42 | #define SPSTATUS_SET_SIGNAL4 0x00040000 43 | #define SPSTATUS_CLEAR_SIGNAL5 0x00080000 44 | #define SPSTATUS_SET_SIGNAL5 0x00100000 45 | #define SPSTATUS_CLEAR_SIGNAL6 0x00200000 46 | #define SPSTATUS_SET_SIGNAL6 0x00800000 47 | #define SPSTATUS_CLEAR_SIGNAL7 0x01000000 48 | #define SPSTATUS_SET_SIGNAL7 0x02000000 49 | 50 | #define SPSTATUS_HALT 0x0001 51 | #define SPSTATUS_BROKE 0x0002 52 | #define SPSTATUS_DMA_BUSY 0x0004 53 | #define SPSTATUS_DMA_FULL 0x0008 54 | #define SPSTATUS_IO_FULL 0x0010 55 | #define SPSTATUS_SINGLE_STEP 0x0020 56 | #define SPSTATUS_INTERRUPT_ON_BREAK 0x0040 57 | #define SPSTATUS_SIGNAL0_SET 0x0080 58 | #define SPSTATUS_SIGNAL1_SET 0x0100 59 | #define SPSTATUS_SIGNAL2_SET 0x0200 60 | #define SPSTATUS_SIGNAL3_SET 0x0400 61 | #define SPSTATUS_SIGNAL4_SET 0x0800 62 | #define SPSTATUS_SIGNAL5_SET 0x1000 63 | #define SPSTATUS_SIGNAL6_SET 0x2000 64 | #define SPSTATUS_SIGNAL7_SET 0x4000 65 | 66 | /* Types */ 67 | /* Types */ 68 | 69 | typedef struct 70 | { 71 | /*0x00*/ u32 type; 72 | /*0x04*/ u32 flags; 73 | 74 | /*0x08*/ u64 *ucode_boot; 75 | /*0x0C*/ u32 ucode_boot_size; 76 | 77 | /*0x10*/ u64 *ucode; 78 | /*0x14*/ u32 ucode_size; 79 | 80 | /*0x18*/ u64 *ucode_data; 81 | /*0x1C*/ u32 ucode_data_size; 82 | 83 | /*0x20*/ u64 *dram_stack; 84 | /*0x24*/ u32 dram_stack_size; 85 | 86 | /*0x28*/ u64 *output_buff; 87 | /*0x2C*/ u64 *output_buff_size; 88 | 89 | /*0x30*/ u64 *data_ptr; 90 | /*0x34*/ u32 data_size; 91 | 92 | /*0x38*/ u64 *yield_data_ptr; 93 | /*0x3C*/ u32 yield_data_size; 94 | } OSTask_t; // size = 0x40 95 | 96 | typedef union { 97 | OSTask_t t; 98 | long long int force_structure_alignment; 99 | } OSTask; 100 | 101 | typedef u32 OSYieldResult; 102 | 103 | /* Functions */ 104 | 105 | #define osSpTaskStart(p) \ 106 | osSpTaskLoad(p); \ 107 | osSpTaskStartGo(p); 108 | 109 | void osSpTaskLoad(OSTask *task); 110 | void osSpTaskStartGo(OSTask *task); 111 | void osSpTaskYield(void); 112 | OSYieldResult osSpTaskYielded(OSTask *task); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /include/PR/ucode.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_UCODE_H_ 2 | #define _ULTRA64_UCODE_H_ 3 | 4 | #define SP_DRAM_STACK_SIZE8 0x400 5 | #define SP_UCODE_SIZE 0x1000 6 | #define SP_UCODE_DATA_SIZE 0x800 7 | 8 | // standard boot ucode 9 | extern u64 rspF3DBootStart[], rspF3DBootEnd[]; 10 | 11 | // F3D ucode 12 | extern u64 rspF3DStart[], rspF3DEnd[]; 13 | 14 | // F3D ucode data 15 | extern u64 rspF3DDataStart[], rspF3DDataEnd[]; 16 | 17 | // aspMain (audio) ucode 18 | extern u64 rspAspMainStart[], rspAspMainEnd[]; 19 | 20 | // aspMain ucode data 21 | extern u64 rspAspMainDataStart[], rspAspMainDataEnd[]; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/PR/ultratypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_TYPES_H_ 2 | #define _ULTRA64_TYPES_H_ 3 | 4 | #ifndef NULL 5 | #define NULL (void *)0 6 | #endif 7 | 8 | #define TRUE 1 9 | #define FALSE 0 10 | 11 | typedef signed char s8; 12 | typedef unsigned char u8; 13 | typedef signed short int s16; 14 | typedef unsigned short int u16; 15 | typedef signed int s32; 16 | typedef unsigned int u32; 17 | typedef signed long long int s64; 18 | typedef unsigned long long int u64; 19 | 20 | typedef volatile u8 vu8; 21 | typedef volatile u16 vu16; 22 | typedef volatile u32 vu32; 23 | typedef volatile u64 vu64; 24 | typedef volatile s8 vs8; 25 | typedef volatile s16 vs16; 26 | typedef volatile s32 vs32; 27 | typedef volatile s64 vs64; 28 | 29 | typedef float f32; 30 | typedef double f64; 31 | 32 | typedef unsigned long size_t; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/math.h: -------------------------------------------------------------------------------- 1 | #ifndef _MATH_H_ 2 | #define _MATH_H_ 3 | 4 | #define M_PI 3.14159265358979323846 5 | 6 | float sinf(float); 7 | double sin(double); 8 | float cosf(float); 9 | double cos(double); 10 | 11 | float sqrtf(float); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/ultra64.h: -------------------------------------------------------------------------------- 1 | #ifndef _ULTRA64_H_ 2 | #define _ULTRA64_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /macros.inc: -------------------------------------------------------------------------------- 1 | # common macros 2 | 3 | .macro glabel label 4 | .global \label 5 | \label: 6 | .endm 7 | -------------------------------------------------------------------------------- /src/base/EF98.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | OSViMode ViModes[42]; 4 | 5 | void ModifyPalViMode() 6 | { 7 | ViModes[16].fldRegs[0].vStart = (u32)0x00330251; 8 | ViModes[16].fldRegs[0].yScale = (u32)0x0000036d; 9 | } 10 | -------------------------------------------------------------------------------- /src/base/EF98.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void ModifyPalViMode() 4 | -------------------------------------------------------------------------------- /src/base/F618.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func_8000F618() 4 | { 5 | func_8000A160(); 6 | func_8001F310(OS_VI_GAMMA_OFF); 7 | func_8001F310(OS_VI_DITHER_FILTER_ON); 8 | } 9 | -------------------------------------------------------------------------------- /src/base/F618.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void func_8000F618() 4 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | mio0 2 | n64cksum 3 | n64graphics 4 | textconv 5 | patch_libultra_math 6 | iplfontutil 7 | n64graphics_ci 8 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | CC := gcc 2 | CFLAGS := -I . -Wall -Wextra -pedantic -std=c99 -O3 -s 3 | PROGRAMS := n64graphics n64graphics_ci mio0 n64cksum textconv patch_libultra_math iplfontutil 4 | 5 | n64graphics_SOURCES := n64graphics.c utils.c 6 | n64graphics_CFLAGS := -DN64GRAPHICS_STANDALONE 7 | 8 | n64graphics_ci_SOURCES := n64graphics_ci_dir/n64graphics_ci.c n64graphics_ci_dir/exoquant/exoquant.c n64graphics_ci_dir/utils.c 9 | 10 | mio0_SOURCES := libmio0.c 11 | mio0_CFLAGS := -DMIO0_STANDALONE 12 | 13 | n64cksum_SOURCES := n64cksum.c libmio0.c libsm64.c utils.c 14 | 15 | textconv_SOURCES := textconv.c utf8.c hashtable.c 16 | patch_libultra_math_SOURCES := patch_libultra_math.c 17 | 18 | iplfontutil_SOURCES := iplfontutil.c 19 | 20 | all: $(PROGRAMS) 21 | 22 | clean: 23 | $(RM) $(PROGRAMS) 24 | 25 | define COMPILE 26 | $(1): $($1_SOURCES) 27 | $(CC) $(CFLAGS) $($1_CFLAGS) $$^ -lm -o $$@ 28 | endef 29 | 30 | $(foreach p,$(PROGRAMS),$(eval $(call COMPILE,$(p)))) 31 | -------------------------------------------------------------------------------- /tools/asm_processor/build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import os 4 | import shlex 5 | import subprocess 6 | import tempfile 7 | 8 | dir_path = os.path.dirname(os.path.realpath(__file__)) 9 | asm_processor = ['python3', os.path.join(dir_path, "asm-processor.py")] 10 | prelude = os.path.join(dir_path, "prelude.inc") 11 | 12 | all_args = sys.argv[1:] 13 | sep1 = all_args.index('--') 14 | sep2 = all_args.index('--', sep1+1) 15 | 16 | compiler = all_args[:sep1] 17 | 18 | assembler = all_args[sep1+1:sep2] 19 | assembler_sh = ' '.join(shlex.quote(x) for x in assembler) 20 | 21 | compile_args = all_args[sep2+1:] 22 | in_file = compile_args[-1] 23 | out_ind = compile_args.index('-o') 24 | out_file = compile_args[out_ind + 1] 25 | del compile_args[-1] 26 | del compile_args[out_ind + 1] 27 | del compile_args[out_ind] 28 | 29 | in_dir = os.path.split(os.path.realpath(in_file))[0] 30 | opt_flags = [x for x in compile_args if x in ['-g', '-O2', '-framepointer']] 31 | 32 | preprocessed_file = tempfile.NamedTemporaryFile(prefix='preprocessed', suffix='.c') 33 | 34 | subprocess.check_call(asm_processor + opt_flags + [in_file], stdout=preprocessed_file) 35 | subprocess.check_call(compiler + compile_args + ['-I', in_dir, '-o', out_file, preprocessed_file.name]) 36 | subprocess.check_call(asm_processor + opt_flags + [in_file, '--post-process', out_file, '--assembler', assembler_sh, '--asm-prelude', prelude]) 37 | -------------------------------------------------------------------------------- /tools/asm_processor/prelude.inc: -------------------------------------------------------------------------------- 1 | .set noat 2 | .set noreorder 3 | .set gp=64 4 | .include "macros.inc" 5 | 6 | -------------------------------------------------------------------------------- /tools/calc_bss.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Given a list of header files, compute the bss index that results from 3 | # including them. (See prevent_bss_reordering.h for more information.) 4 | 5 | TEMPC=$(mktemp -t bss.XXXXXXX.c) 6 | TEMPO=$(mktemp -t bss.XXXXXXX.o) 7 | trap "rm -f $TEMPC $TEMPO" EXIT 8 | 9 | set -e 10 | 11 | if [[ $# = 0 ]]; then 12 | echo "Usage: ./tools/calc_bss.sh file1.h file2.h ..." >&2 13 | exit 1 14 | fi 15 | 16 | if [ -z "$QEMU_IRIX" ]; then 17 | echo "env variable QEMU_IRIX should point to the qemu-mips binary" >&2 18 | exit 1 19 | fi 20 | 21 | if [ -z "$CROSS" ]; then 22 | CROSS=mips-linux-gnu- 23 | fi 24 | 25 | # bss indexing starts at 3 26 | for I in {3..255}; do 27 | echo "char bss$I;" >> $TEMPC 28 | done 29 | for I in {0..2}; do 30 | echo "char bss$I;" >> $TEMPC 31 | done 32 | 33 | while [[ $# -gt 0 ]]; do 34 | echo "#include \"$1\"" >> $TEMPC 35 | shift 36 | done 37 | 38 | echo "char measurement;" >> $TEMPC 39 | 40 | $QEMU_IRIX -silent -L $IRIX_ROOT $IRIX_ROOT/usr/bin/cc -c -non_shared -G 0 \ 41 | -g -Xcpluscomm -mips2 -I $(pwd)/include/ $TEMPC -o $TEMPO 42 | 43 | LINE=$(${CROSS}objdump -t $TEMPO | grep measurement | cut -d' ' -f1) 44 | NUM=$((0x$LINE - 1)) 45 | echo "bss index: $NUM" 46 | -------------------------------------------------------------------------------- /tools/hashtable.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "hashtable.h" 7 | 8 | struct HashNode 9 | { 10 | struct HashNode *next; 11 | uint8_t value[]; 12 | }; 13 | 14 | struct HashTable 15 | { 16 | HashFunc func; 17 | HashValueCmpFunc cmp; 18 | int size; 19 | int elemSize; 20 | struct HashNode *table[]; 21 | }; 22 | 23 | struct HashTable *hashtable_new(HashFunc func, HashValueCmpFunc cmp, int size, 24 | int elemSize) 25 | { 26 | struct HashTable *ht = malloc(sizeof(*ht) + size * sizeof(ht->table[0])); 27 | 28 | ht->func = func; 29 | ht->cmp = cmp; 30 | ht->size = size; 31 | ht->elemSize = elemSize; 32 | memset(ht->table, 0, ht->size * sizeof(ht->table[0])); 33 | return ht; 34 | } 35 | 36 | void hashtable_free(struct HashTable *ht) 37 | { 38 | int i; 39 | 40 | for (i = 0; i < ht->size; i++) 41 | { 42 | struct HashNode *node = ht->table[i]; 43 | 44 | while (node != NULL) 45 | { 46 | struct HashNode *next = node->next; 47 | 48 | free(node); 49 | node = next; 50 | } 51 | } 52 | free(ht); 53 | } 54 | 55 | void hashtable_insert(struct HashTable *ht, const void *value) 56 | { 57 | unsigned int key = ht->func(value) % ht->size; 58 | struct HashNode *node = malloc(sizeof(*node) + ht->elemSize); 59 | 60 | node->next = NULL; 61 | memcpy(node->value, value, ht->elemSize); 62 | 63 | if (ht->table[key] == NULL) 64 | { 65 | ht->table[key] = node; 66 | } 67 | else 68 | { 69 | struct HashNode *parent = ht->table[key]; 70 | 71 | while (parent->next != NULL) 72 | parent = parent->next; 73 | parent->next = node; 74 | } 75 | } 76 | 77 | void *hashtable_query(struct HashTable *ht, const void *value) 78 | { 79 | unsigned int key = ht->func(value) % ht->size; 80 | struct HashNode *node = ht->table[key]; 81 | 82 | while (node != NULL) 83 | { 84 | if (ht->cmp(node->value, value)) 85 | return node->value; 86 | node = node->next; 87 | } 88 | return NULL; 89 | } 90 | -------------------------------------------------------------------------------- /tools/hashtable.h: -------------------------------------------------------------------------------- 1 | #ifndef HASHTABLE_H_ 2 | #define HASHTABLE_H_ 3 | 4 | typedef unsigned int (*HashFunc)(const void *item); 5 | typedef int (*HashValueCmpFunc)(const void *a, const void *b); 6 | struct HashTable; 7 | 8 | struct HashTable *hashtable_new(HashFunc func, HashValueCmpFunc cmp, int size, int valueSize); 9 | void hashtable_free(struct HashTable *ht); 10 | void hashtable_insert(struct HashTable *ht, const void *value); 11 | void *hashtable_query(struct HashTable *ht, const void *value); 12 | 13 | #endif // HASHTABLE_H_ 14 | -------------------------------------------------------------------------------- /tools/ido5.3_compiler/lib/libmalloc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/lib/libmalloc.so -------------------------------------------------------------------------------- /tools/ido5.3_compiler/lib/libmalloc_old.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/lib/libmalloc_old.so -------------------------------------------------------------------------------- /tools/ido5.3_compiler/lib/rld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/lib/rld -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/bin/cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/bin/cc -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/as0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/as0 -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/as1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/as1 -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/cfe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/cfe -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/crt1.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/crt1.o -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/libc.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/libc.so.1 -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/libexc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/libexc.so -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/libgen.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/libgen.so -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/libm.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/libm.so -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/ugen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/ugen -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/ujoin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/ujoin -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/uld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/uld -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/umerge: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/umerge -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/uopt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/uopt -------------------------------------------------------------------------------- /tools/ido5.3_compiler/usr/lib/usplit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaytheham/body-harvest-decompilation/9bd98d141de4b314a19574b3f949c175a2b74e14/tools/ido5.3_compiler/usr/lib/usplit -------------------------------------------------------------------------------- /tools/iplfontutil.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define STBI_NO_LINEAR 6 | #define STBI_NO_PSD 7 | #define STBI_NO_TGA 8 | #define STBI_NO_HDR 9 | #define STBI_NO_PIC 10 | #define STBI_NO_PNM 11 | #define STB_IMAGE_WRITE_IMPLEMENTATION 12 | #include 13 | #define STB_IMAGE_IMPLEMENTATION 14 | #include 15 | 16 | #define GETBIT(buf, idx) ((buf[(idx)/8] >> (7-((idx)%8))) & 1) 17 | #define SETBIT(buf, idx) buf[(idx)/8] |= (1 << (7-((idx)%8))) 18 | 19 | #define IPL3_FONT_NCHARS 50 20 | #define IPL3_FONT_CHAR_W 13 21 | #define IPL3_FONT_CHAR_H 14 22 | #define IPL3_FONT_CHAR_NPIXELS (IPL3_FONT_CHAR_W * IPL3_FONT_CHAR_H) 23 | #define IPL3_FONT_CHAR_NBITS (IPL3_FONT_CHAR_NPIXELS + 2) 24 | #define IPL3_FONT_CHAR_NBYTES (IPL3_FONT_CHAR_NBITS / 8) 25 | 26 | #define IPL3_FONT_FILE_SIZE ((IPL3_FONT_NCHARS * IPL3_FONT_CHAR_NBYTES) + 0x12) 27 | 28 | int ipl3font_decode(const char *binPath, const char *imgPath) 29 | { 30 | FILE *binfp = fopen(binPath, "rb"); 31 | 32 | if(binfp == NULL) 33 | { 34 | printf("error: could not open %s for input\n", binPath); 35 | return EXIT_FAILURE; 36 | } 37 | 38 | fseek(binfp, 0, SEEK_END); 39 | size_t binSize = ftell(binfp); 40 | 41 | if(binSize != IPL3_FONT_FILE_SIZE) 42 | { 43 | printf("error: font bin size invalid (must be 0x%X bytes)\n", IPL3_FONT_FILE_SIZE); 44 | fclose(binfp); 45 | return EXIT_FAILURE; 46 | } 47 | 48 | rewind(binfp); 49 | 50 | char *binBuf = (char *) malloc(binSize); 51 | if(fread(binBuf, 1, binSize, binfp) != binSize) 52 | { 53 | printf("error: failed to read from %s\n", binPath); 54 | fclose(binfp); 55 | return EXIT_FAILURE; 56 | } 57 | fclose(binfp); 58 | 59 | uint32_t outSize = IPL3_FONT_NCHARS * IPL3_FONT_CHAR_NPIXELS * sizeof(uint32_t); 60 | uint32_t *outRgba32 = (uint32_t *) malloc(outSize); 61 | int outIdx = 0; 62 | 63 | for(int nChar = 0; nChar < IPL3_FONT_NCHARS; nChar++) 64 | { 65 | for(int nRow = 0; nRow < IPL3_FONT_CHAR_H; nRow++) 66 | { 67 | for(int nCol = 0; nCol < IPL3_FONT_CHAR_W; nCol++) 68 | { 69 | int idx = (nChar * IPL3_FONT_CHAR_NBITS) + (nRow * IPL3_FONT_CHAR_W) + nCol; 70 | int bit = GETBIT(binBuf, idx); 71 | outRgba32[outIdx++] = (bit == 1) ? 0xFFFFFFFF : 0xFF000000; 72 | } 73 | } 74 | } 75 | 76 | int stbres = stbi_write_png(imgPath, 77 | IPL3_FONT_CHAR_W, 78 | IPL3_FONT_NCHARS * IPL3_FONT_CHAR_H, 79 | 4, 80 | outRgba32, 81 | IPL3_FONT_CHAR_W * sizeof(uint32_t)); 82 | 83 | if(stbres == 0) 84 | { 85 | printf("error: failed to write %s\n", imgPath); 86 | free(outRgba32); 87 | free(binBuf); 88 | return EXIT_FAILURE; 89 | } 90 | 91 | free(outRgba32); 92 | free(binBuf); 93 | return EXIT_SUCCESS; 94 | } 95 | 96 | int ipl3font_encode(const char *imgPath, const char *binPath) 97 | { 98 | int x, y, channels_in_file; 99 | uint32_t *inRgba32 = (uint32_t *) stbi_load(imgPath, &x, &y, &channels_in_file, 4); 100 | 101 | if(inRgba32 == NULL) 102 | { 103 | printf("error: failed to load %s\n", imgPath); 104 | return EXIT_FAILURE; 105 | } 106 | 107 | if(x != IPL3_FONT_CHAR_W || y != IPL3_FONT_NCHARS * IPL3_FONT_CHAR_H) 108 | { 109 | printf("error: invalid ipl3 font image dimensions (must be %dx%d)\n", 110 | IPL3_FONT_CHAR_W, IPL3_FONT_NCHARS * IPL3_FONT_CHAR_H); 111 | stbi_image_free(inRgba32); 112 | return EXIT_FAILURE; 113 | } 114 | 115 | char *out = calloc(IPL3_FONT_FILE_SIZE, 1); 116 | 117 | int inIdx = 0; 118 | 119 | for(int nChar = 0; nChar < IPL3_FONT_NCHARS; nChar++) 120 | { 121 | for(int nRow = 0; nRow < IPL3_FONT_CHAR_H; nRow++) 122 | { 123 | for(int nCol = 0; nCol < IPL3_FONT_CHAR_W; nCol++) 124 | { 125 | // source pixels that are not 0xFFFFFFFF are ignored 126 | if(inRgba32[inIdx++] == 0xFFFFFFFF) 127 | { 128 | int idx = (nChar * IPL3_FONT_CHAR_NBITS) + (nRow * IPL3_FONT_CHAR_W) + nCol; 129 | SETBIT(out, idx); 130 | } 131 | } 132 | } 133 | } 134 | 135 | FILE * outfp = fopen(binPath, "wb"); 136 | 137 | if(outfp == NULL) 138 | { 139 | printf("error: failed to write to %s\n", binPath); 140 | stbi_image_free(inRgba32); 141 | free(out); 142 | return EXIT_FAILURE; 143 | } 144 | 145 | fwrite(out, 1, IPL3_FONT_FILE_SIZE, outfp); 146 | fclose(outfp); 147 | 148 | stbi_image_free(inRgba32); 149 | free(out); 150 | 151 | return EXIT_SUCCESS; 152 | } 153 | 154 | int main(int argc, const char *argv[]) 155 | { 156 | if(argc < 4) 157 | { 158 | printf("error: no paths\n"); 159 | printf("iplfontutil e \n"); 160 | printf("iplfontutil d \n"); 161 | return EXIT_FAILURE; 162 | } 163 | 164 | const char *mode = argv[1]; 165 | 166 | if(strcmp(mode, "e") == 0) 167 | { 168 | return ipl3font_encode(argv[2], argv[3]); 169 | } 170 | else if(strcmp(mode, "d") == 0) 171 | { 172 | return ipl3font_decode(argv[2], argv[3]); 173 | } 174 | else 175 | { 176 | printf("error: unknown mode\n"); 177 | return EXIT_FAILURE; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /tools/libmio0.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "libmio0.h" 6 | #include "utils.h" 7 | 8 | // defines 9 | 10 | #define MIO0_VERSION "0.1" 11 | 12 | #define GET_BIT(buf, bit) ((buf)[(bit) / 8] & (1 << (7 - ((bit) % 8)))) 13 | 14 | // types 15 | typedef struct 16 | { 17 | int *indexes; 18 | int allocated; 19 | int count; 20 | int start; 21 | } lookback; 22 | 23 | // functions 24 | #define LOOKBACK_COUNT 256 25 | #define LOOKBACK_INIT_SIZE 128 26 | static lookback *lookback_init(void) 27 | { 28 | lookback *lb = malloc(LOOKBACK_COUNT * sizeof(*lb)); 29 | for (int i = 0; i < LOOKBACK_COUNT; i++) { 30 | lb[i].allocated = LOOKBACK_INIT_SIZE; 31 | lb[i].indexes = malloc(lb[i].allocated * sizeof(*lb[i].indexes)); 32 | lb[i].count = 0; 33 | lb[i].start = 0; 34 | } 35 | return lb; 36 | } 37 | 38 | static void lookback_free(lookback *lb) 39 | { 40 | for (int i = 0; i < LOOKBACK_COUNT; i++) { 41 | free(lb[i].indexes); 42 | } 43 | free(lb); 44 | } 45 | 46 | static inline void lookback_push(lookback *lkbk, unsigned char val, int index) 47 | { 48 | lookback *lb = &lkbk[val]; 49 | if (lb->count == lb->allocated) { 50 | lb->allocated *= 4; 51 | lb->indexes = realloc(lb->indexes, lb->allocated * sizeof(*lb->indexes)); 52 | } 53 | lb->indexes[lb->count++] = index; 54 | } 55 | 56 | static void PUT_BIT(unsigned char *buf, int bit, int val) 57 | { 58 | unsigned char mask = 1 << (7 - (bit % 8)); 59 | unsigned int offset = bit / 8; 60 | buf[offset] = (buf[offset] & ~(mask)) | (val ? mask : 0); 61 | } 62 | 63 | // used to find longest matching stream in buffer 64 | // buf: buffer 65 | // start_offset: offset in buf to look back from 66 | // max_search: max number of bytes to find 67 | // found_offset: returned offset found (0 if none found) 68 | // returns max length of matching stream (0 if none found) 69 | static int find_longest(const unsigned char *buf, int start_offset, int max_search, int *found_offset, lookback *lkbk) 70 | { 71 | int best_length = 0; 72 | int best_offset = 0; 73 | int cur_length; 74 | int search_len; 75 | int farthest, off, i; 76 | int lb_idx; 77 | const unsigned char first = buf[start_offset]; 78 | lookback *lb = &lkbk[first]; 79 | 80 | // buf 81 | // | off start max 82 | // V |+i-> |+i-> | 83 | // |--------------raw-data-----------------| 84 | // |+i-> | |+i-> 85 | // +cur_length 86 | 87 | // check at most the past 4096 values 88 | farthest = MAX(start_offset - 4096, 0); 89 | // find starting index 90 | for (lb_idx = lb->start; lb_idx < lb->count && lb->indexes[lb_idx] < farthest; lb_idx++) {} 91 | lb->start = lb_idx; 92 | for ( ; lb_idx < lb->count && lb->indexes[lb_idx] < start_offset; lb_idx++) { 93 | off = lb->indexes[lb_idx]; 94 | // check at most requested max or up until start 95 | search_len = MIN(max_search, start_offset - off); 96 | for (i = 0; i < search_len; i++) { 97 | if (buf[start_offset + i] != buf[off + i]) { 98 | break; 99 | } 100 | } 101 | cur_length = i; 102 | // if matched up until start, continue matching in already matched parts 103 | if (cur_length == search_len) { 104 | // check at most requested max less current length 105 | search_len = max_search - cur_length; 106 | for (i = 0; i < search_len; i++) { 107 | if (buf[start_offset + cur_length + i] != buf[off + i]) { 108 | break; 109 | } 110 | } 111 | cur_length += i; 112 | } 113 | if (cur_length > best_length) { 114 | best_offset = start_offset - off; 115 | best_length = cur_length; 116 | } 117 | } 118 | 119 | // return best reverse offset and length (may be 0) 120 | *found_offset = best_offset; 121 | return best_length; 122 | } 123 | 124 | // decode MIO0 header 125 | // returns 1 if valid header, 0 otherwise 126 | int mio0_decode_header(const unsigned char *buf, mio0_header_t *head) 127 | { 128 | if (!memcmp(buf, "MIO0", 4)) { 129 | head->dest_size = read_u32_be(&buf[4]); 130 | head->comp_offset = read_u32_be(&buf[8]); 131 | head->uncomp_offset = read_u32_be(&buf[12]); 132 | return 1; 133 | } 134 | return 0; 135 | } 136 | 137 | void mio0_encode_header(unsigned char *buf, const mio0_header_t *head) 138 | { 139 | memcpy(buf, "MIO0", 4); 140 | write_u32_be(&buf[4], head->dest_size); 141 | write_u32_be(&buf[8], head->comp_offset); 142 | write_u32_be(&buf[12], head->uncomp_offset); 143 | } 144 | 145 | int mio0_decode(const unsigned char *in, unsigned char *out, unsigned int *end) 146 | { 147 | mio0_header_t head; 148 | unsigned int bytes_written = 0; 149 | int bit_idx = 0; 150 | int comp_idx = 0; 151 | int uncomp_idx = 0; 152 | int valid; 153 | 154 | // extract header 155 | valid = mio0_decode_header(in, &head); 156 | // verify MIO0 header 157 | if (!valid) { 158 | return -2; 159 | } 160 | 161 | // decode data 162 | while (bytes_written < head.dest_size) { 163 | if (GET_BIT(&in[MIO0_HEADER_LENGTH], bit_idx)) { 164 | // 1 - pull uncompressed data 165 | out[bytes_written] = in[head.uncomp_offset + uncomp_idx]; 166 | bytes_written++; 167 | uncomp_idx++; 168 | } else { 169 | // 0 - read compressed data 170 | int idx; 171 | int length; 172 | int i; 173 | const unsigned char *vals = &in[head.comp_offset + comp_idx]; 174 | comp_idx += 2; 175 | length = ((vals[0] & 0xF0) >> 4) + 3; 176 | idx = ((vals[0] & 0x0F) << 8) + vals[1] + 1; 177 | for (i = 0; i < length; i++) { 178 | out[bytes_written] = out[bytes_written - idx]; 179 | bytes_written++; 180 | } 181 | } 182 | bit_idx++; 183 | } 184 | 185 | if (end) { 186 | *end = head.uncomp_offset + uncomp_idx; 187 | } 188 | 189 | return bytes_written; 190 | } 191 | 192 | int mio0_encode(const unsigned char *in, unsigned int length, unsigned char *out) 193 | { 194 | unsigned char *bit_buf; 195 | unsigned char *comp_buf; 196 | unsigned char *uncomp_buf; 197 | unsigned int bit_length; 198 | unsigned int comp_offset; 199 | unsigned int uncomp_offset; 200 | unsigned int bytes_proc = 0; 201 | int bytes_written; 202 | int bit_idx = 0; 203 | int comp_idx = 0; 204 | int uncomp_idx = 0; 205 | lookback *lookbacks; 206 | 207 | // initialize lookback buffer 208 | lookbacks = lookback_init(); 209 | 210 | // allocate some temporary buffers worst case size 211 | bit_buf = malloc((length + 7) / 8); // 1-bit/byte 212 | comp_buf = malloc(length); // 16-bits/2bytes 213 | uncomp_buf = malloc(length); // all uncompressed 214 | memset(bit_buf, 0, (length + 7) / 8); 215 | 216 | // encode data 217 | // special case for first byte 218 | lookback_push(lookbacks, in[0], 0); 219 | uncomp_buf[uncomp_idx] = in[0]; 220 | uncomp_idx += 1; 221 | bytes_proc += 1; 222 | PUT_BIT(bit_buf, bit_idx++, 1); 223 | while (bytes_proc < length) { 224 | int offset; 225 | int max_length = MIN(length - bytes_proc, 18); 226 | int longest_match = find_longest(in, bytes_proc, max_length, &offset, lookbacks); 227 | // push current byte before checking next longer match 228 | lookback_push(lookbacks, in[bytes_proc], bytes_proc); 229 | if (longest_match > 2) { 230 | int lookahead_offset; 231 | // lookahead to next byte to see if longer match 232 | int lookahead_length = MIN(length - bytes_proc - 1, 18); 233 | int lookahead_match = find_longest(in, bytes_proc + 1, lookahead_length, &lookahead_offset, lookbacks); 234 | // better match found, use uncompressed + lookahead compressed 235 | if ((longest_match + 1) < lookahead_match) { 236 | // uncompressed byte 237 | uncomp_buf[uncomp_idx] = in[bytes_proc]; 238 | uncomp_idx++; 239 | PUT_BIT(bit_buf, bit_idx, 1); 240 | bytes_proc++; 241 | longest_match = lookahead_match; 242 | offset = lookahead_offset; 243 | bit_idx++; 244 | lookback_push(lookbacks, in[bytes_proc], bytes_proc); 245 | } 246 | // first byte already pushed above 247 | for (int i = 1; i < longest_match; i++) { 248 | lookback_push(lookbacks, in[bytes_proc + i], bytes_proc + i); 249 | } 250 | // compressed block 251 | comp_buf[comp_idx] = (((longest_match - 3) & 0x0F) << 4) | 252 | (((offset - 1) >> 8) & 0x0F); 253 | comp_buf[comp_idx + 1] = (offset - 1) & 0xFF; 254 | comp_idx += 2; 255 | PUT_BIT(bit_buf, bit_idx, 0); 256 | bytes_proc += longest_match; 257 | } else { 258 | // uncompressed byte 259 | uncomp_buf[uncomp_idx] = in[bytes_proc]; 260 | uncomp_idx++; 261 | PUT_BIT(bit_buf, bit_idx, 1); 262 | bytes_proc++; 263 | } 264 | bit_idx++; 265 | } 266 | 267 | // compute final sizes and offsets 268 | // +7 so int division accounts for all bits 269 | bit_length = ((bit_idx + 7) / 8); 270 | // compressed data after control bits and aligned to 4-byte boundary 271 | comp_offset = ALIGN(MIO0_HEADER_LENGTH + bit_length, 4); 272 | uncomp_offset = comp_offset + comp_idx; 273 | bytes_written = uncomp_offset + uncomp_idx; 274 | 275 | // output header 276 | memcpy(out, "MIO0", 4); 277 | write_u32_be(&out[4], length); 278 | write_u32_be(&out[8], comp_offset); 279 | write_u32_be(&out[12], uncomp_offset); 280 | // output data 281 | memcpy(&out[MIO0_HEADER_LENGTH], bit_buf, bit_length); 282 | memcpy(&out[comp_offset], comp_buf, comp_idx); 283 | memcpy(&out[uncomp_offset], uncomp_buf, uncomp_idx); 284 | 285 | // free allocated buffers 286 | free(bit_buf); 287 | free(comp_buf); 288 | free(uncomp_buf); 289 | lookback_free(lookbacks); 290 | 291 | return bytes_written; 292 | } 293 | 294 | int mio0_decode_file(const char *in_file, unsigned long offset, const char *out_file) 295 | { 296 | mio0_header_t head; 297 | FILE *in; 298 | FILE *out; 299 | unsigned char *in_buf = NULL; 300 | unsigned char *out_buf = NULL; 301 | long file_size; 302 | int ret_val = 0; 303 | size_t bytes_read; 304 | int bytes_decoded; 305 | int bytes_written; 306 | int valid; 307 | 308 | in = fopen(in_file, "rb"); 309 | if (in == NULL) { 310 | return 1; 311 | } 312 | 313 | // allocate buffer to read from offset to end of file 314 | fseek(in, 0, SEEK_END); 315 | file_size = ftell(in); 316 | in_buf = malloc(file_size - offset); 317 | fseek(in, offset, SEEK_SET); 318 | 319 | // read bytes 320 | bytes_read = fread(in_buf, 1, file_size - offset, in); 321 | if (bytes_read != file_size - offset) { 322 | ret_val = 2; 323 | goto free_all; 324 | } 325 | 326 | // verify header 327 | valid = mio0_decode_header(in_buf, &head); 328 | if (!valid) { 329 | ret_val = 3; 330 | goto free_all; 331 | } 332 | out_buf = malloc(head.dest_size); 333 | 334 | // decompress MIO0 encoded data 335 | bytes_decoded = mio0_decode(in_buf, out_buf, NULL); 336 | if (bytes_decoded < 0) { 337 | ret_val = 3; 338 | goto free_all; 339 | } 340 | 341 | // open output file 342 | out = fopen(out_file, "wb"); 343 | if (out == NULL) { 344 | ret_val = 4; 345 | goto free_all; 346 | } 347 | 348 | // write data to file 349 | bytes_written = fwrite(out_buf, 1, bytes_decoded, out); 350 | if (bytes_written != bytes_decoded) { 351 | ret_val = 5; 352 | } 353 | 354 | // clean up 355 | fclose(out); 356 | free_all: 357 | if (out_buf) { 358 | free(out_buf); 359 | } 360 | if (in_buf) { 361 | free(in_buf); 362 | } 363 | fclose(in); 364 | 365 | return ret_val; 366 | } 367 | 368 | int mio0_encode_file(const char *in_file, const char *out_file) 369 | { 370 | FILE *in; 371 | FILE *out; 372 | unsigned char *in_buf = NULL; 373 | unsigned char *out_buf = NULL; 374 | size_t file_size; 375 | size_t bytes_read; 376 | int bytes_encoded; 377 | int bytes_written; 378 | int ret_val = 0; 379 | 380 | in = fopen(in_file, "rb"); 381 | if (in == NULL) { 382 | return 1; 383 | } 384 | 385 | // allocate buffer to read entire contents of files 386 | fseek(in, 0, SEEK_END); 387 | file_size = ftell(in); 388 | fseek(in, 0, SEEK_SET); 389 | in_buf = malloc(file_size); 390 | 391 | // read bytes 392 | bytes_read = fread(in_buf, 1, file_size, in); 393 | if (bytes_read != file_size) { 394 | ret_val = 2; 395 | goto free_all; 396 | } 397 | 398 | // allocate worst case length 399 | out_buf = malloc(MIO0_HEADER_LENGTH + ((file_size+7)/8) + file_size); 400 | 401 | // compress data in MIO0 format 402 | bytes_encoded = mio0_encode(in_buf, file_size, out_buf); 403 | 404 | // open output file 405 | out = fopen(out_file, "wb"); 406 | if (out == NULL) { 407 | ret_val = 4; 408 | goto free_all; 409 | } 410 | 411 | // write data to file 412 | bytes_written = fwrite(out_buf, 1, bytes_encoded, out); 413 | if (bytes_written != bytes_encoded) { 414 | ret_val = 5; 415 | } 416 | 417 | // clean up 418 | fclose(out); 419 | free_all: 420 | if (out_buf) { 421 | free(out_buf); 422 | } 423 | if (in_buf) { 424 | free(in_buf); 425 | } 426 | fclose(in); 427 | 428 | return ret_val; 429 | } 430 | 431 | // mio0 standalone executable 432 | #ifdef MIO0_STANDALONE 433 | typedef struct 434 | { 435 | char *in_filename; 436 | char *out_filename; 437 | unsigned int offset; 438 | int compress; 439 | } arg_config; 440 | 441 | static arg_config default_config = 442 | { 443 | NULL, 444 | NULL, 445 | 0, 446 | 1 447 | }; 448 | 449 | static void print_usage(void) 450 | { 451 | ERROR("Usage: mio0 [-c / -d] [-o OFFSET] FILE [OUTPUT]\n" 452 | "\n" 453 | "mio0 v" MIO0_VERSION ": MIO0 compression and decompression tool\n" 454 | "\n" 455 | "Optional arguments:\n" 456 | " -c compress raw data into MIO0 (default: compress)\n" 457 | " -d decompress MIO0 into raw data\n" 458 | " -o OFFSET starting offset in FILE (default: 0)\n" 459 | "\n" 460 | "File arguments:\n" 461 | " FILE input file\n" 462 | " [OUTPUT] output file (default: FILE.out)\n"); 463 | exit(1); 464 | } 465 | 466 | // parse command line arguments 467 | static void parse_arguments(int argc, char *argv[], arg_config *config) 468 | { 469 | int i; 470 | int file_count = 0; 471 | if (argc < 2) { 472 | print_usage(); 473 | exit(1); 474 | } 475 | for (i = 1; i < argc; i++) { 476 | if (argv[i][0] == '-') { 477 | switch (argv[i][1]) { 478 | case 'c': 479 | config->compress = 1; 480 | break; 481 | case 'd': 482 | config->compress = 0; 483 | break; 484 | case 'o': 485 | if (++i >= argc) { 486 | print_usage(); 487 | } 488 | config->offset = strtoul(argv[i], NULL, 0); 489 | break; 490 | default: 491 | print_usage(); 492 | break; 493 | } 494 | } else { 495 | switch (file_count) { 496 | case 0: 497 | config->in_filename = argv[i]; 498 | break; 499 | case 1: 500 | config->out_filename = argv[i]; 501 | break; 502 | default: // too many 503 | print_usage(); 504 | break; 505 | } 506 | file_count++; 507 | } 508 | } 509 | if (file_count < 1) { 510 | print_usage(); 511 | } 512 | } 513 | 514 | int main(int argc, char *argv[]) 515 | { 516 | char out_filename[FILENAME_MAX]; 517 | arg_config config; 518 | int ret_val; 519 | 520 | // get configuration from arguments 521 | config = default_config; 522 | parse_arguments(argc, argv, &config); 523 | if (config.out_filename == NULL) { 524 | config.out_filename = out_filename; 525 | sprintf(config.out_filename, "%s.out", config.in_filename); 526 | } 527 | 528 | // operation 529 | if (config.compress) { 530 | ret_val = mio0_encode_file(config.in_filename, config.out_filename); 531 | } else { 532 | ret_val = mio0_decode_file(config.in_filename, config.offset, config.out_filename); 533 | } 534 | 535 | switch (ret_val) { 536 | case 1: 537 | ERROR("Error opening input file \"%s\"\n", config.in_filename); 538 | break; 539 | case 2: 540 | ERROR("Error reading from input file \"%s\"\n", config.in_filename); 541 | break; 542 | case 3: 543 | ERROR("Error decoding MIO0 data. Wrong offset (0x%X)?\n", config.offset); 544 | break; 545 | case 4: 546 | ERROR("Error opening output file \"%s\"\n", config.out_filename); 547 | break; 548 | case 5: 549 | ERROR("Error writing bytes to output file \"%s\"\n", config.out_filename); 550 | break; 551 | } 552 | 553 | return ret_val; 554 | } 555 | #endif // MIO0_STANDALONE 556 | 557 | -------------------------------------------------------------------------------- /tools/libmio0.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBMIO0_H_ 2 | #define LIBMIO0_H_ 3 | 4 | // defines 5 | 6 | #define MIO0_HEADER_LENGTH 16 7 | 8 | // typedefs 9 | 10 | typedef struct 11 | { 12 | unsigned int dest_size; 13 | unsigned int comp_offset; 14 | unsigned int uncomp_offset; 15 | } mio0_header_t; 16 | 17 | // function prototypes 18 | 19 | // decode MIO0 header 20 | // returns 1 if valid header, 0 otherwise 21 | int mio0_decode_header(const unsigned char *buf, mio0_header_t *head); 22 | 23 | // encode MIO0 header from struct 24 | void mio0_encode_header(unsigned char *buf, const mio0_header_t *head); 25 | 26 | // decode MIO0 data in memory 27 | // in: buffer containing MIO0 data 28 | // out: buffer for output data 29 | // end: output offset of the last byte decoded from in (set to NULL if unwanted) 30 | // returns bytes extracted to 'out' or negative value on failure 31 | int mio0_decode(const unsigned char *in, unsigned char *out, unsigned int *end); 32 | 33 | // encode MIO0 data in memory 34 | // in: buffer containing raw data 35 | // out: buffer for MIO0 data 36 | // returns size of compressed data in 'out' including MIO0 header 37 | int mio0_encode(const unsigned char *in, unsigned int length, unsigned char *out); 38 | 39 | // decode an entire MIO0 block at an offset from file to output file 40 | // in_file: input filename 41 | // offset: offset to start decoding from in_file 42 | // out_file: output filename 43 | int mio0_decode_file(const char *in_file, unsigned long offset, const char *out_file); 44 | 45 | // encode an entire file 46 | // in_file: input filename containing raw data to be encoded 47 | // out_file: output filename to write MIO0 compressed data to 48 | int mio0_encode_file(const char *in_file, const char *out_file); 49 | 50 | #endif // LIBMIO0_H_ 51 | -------------------------------------------------------------------------------- /tools/libsm64.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBSM64_H_ 2 | #define LIBSM64_H_ 3 | 4 | #define MIO0_DIR "mio0files" 5 | 6 | // typedefs 7 | typedef enum 8 | { 9 | ROM_INVALID, // not valid SM64 ROM 10 | ROM_SM64_BS, // SM64 byte-swapped (BADC) 11 | ROM_SM64_BE, // SM64 big-endian (ABCD) 12 | ROM_SM64_LE, // SM64 little-endian 13 | ROM_SM64_BE_EXT, // SM64 big-endian, extended 14 | } rom_type; 15 | 16 | typedef enum 17 | { 18 | VERSION_UNKNOWN, 19 | VERSION_SM64_U, 20 | VERSION_SM64_E, 21 | VERSION_SM64_J, 22 | VERSION_SM64_SHINDOU, 23 | } rom_version; 24 | 25 | typedef struct 26 | { 27 | char *in_filename; 28 | char *ext_filename; 29 | unsigned int ext_size; 30 | unsigned int padding; 31 | unsigned int alignment; 32 | char fill; 33 | char dump; 34 | } sm64_config; 35 | 36 | // determine ROM type based on data 37 | // buf: buffer containing raw SM64 ROM file data 38 | // length: length of 'buf' 39 | // returns SM64 ROM type or invalid 40 | rom_type sm64_rom_type(unsigned char *buf, unsigned int length); 41 | 42 | // determine SM64 ROM type based on cksum data 43 | // buf: buffer containing raw SM64 ROM file data 44 | // returns SM64 ROM version or unknown 45 | rom_version sm64_rom_version(unsigned char *buf); 46 | 47 | // find and decompress all MIO0 blocks 48 | // config: configuration to determine alignment, padding and size 49 | // in_buf: buffer containing entire contents of SM64 data in big endian 50 | // length: length of in_buf 51 | // out_buf: buffer containing extended SM64 52 | void sm64_decompress_mio0(const sm64_config *config, 53 | unsigned char *in_buf, 54 | unsigned int in_length, 55 | unsigned char *out_buf); 56 | 57 | // update N64 header checksums 58 | // buf: buffer containing ROM data 59 | // checksums are written into the buffer 60 | void sm64_update_checksums(unsigned char *buf); 61 | 62 | #endif // LIBSM64_H_ 63 | -------------------------------------------------------------------------------- /tools/n64cksum.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libsm64.h" 5 | #include "utils.h" 6 | 7 | #define N64CKSUM_VERSION "0.1" 8 | 9 | static void print_usage(void) 10 | { 11 | ERROR("Usage: n64cksum ROM [ROM_OUT]\n" 12 | "\n" 13 | "n64cksum v" N64CKSUM_VERSION ": N64 ROM checksum calculator\n" 14 | "\n" 15 | "File arguments:\n" 16 | " ROM input ROM file\n" 17 | " ROM_OUT output ROM file (default: overwrites input ROM)\n"); 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | unsigned char *rom_data; 23 | char *file_in; 24 | char *file_out; 25 | long length; 26 | long write_length; 27 | if (argc < 2) { 28 | print_usage(); 29 | return EXIT_FAILURE; 30 | } 31 | 32 | file_in = argv[1]; 33 | if (argc > 2) { 34 | file_out = argv[2]; 35 | } else { 36 | file_out = argv[1]; 37 | } 38 | 39 | length = read_file(file_in, &rom_data); 40 | if (length < 0) { 41 | ERROR("Error reading input file \"%s\"\n", file_in); 42 | return EXIT_FAILURE; 43 | } 44 | 45 | sm64_update_checksums(rom_data); 46 | 47 | write_length = write_file(file_out, rom_data, length); 48 | 49 | free(rom_data); 50 | 51 | if (write_length != length) { 52 | ERROR("Error writing to output file \"%s\"\n", file_out); 53 | return EXIT_FAILURE; 54 | } 55 | 56 | return EXIT_SUCCESS; 57 | } 58 | -------------------------------------------------------------------------------- /tools/n64graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef N64GRAPHICS_H_ 2 | #define N64GRAPHICS_H_ 3 | 4 | #include 5 | 6 | // intermediate formats 7 | typedef struct _rgba 8 | { 9 | uint8_t red; 10 | uint8_t green; 11 | uint8_t blue; 12 | uint8_t alpha; 13 | } rgba; 14 | 15 | typedef struct _ia 16 | { 17 | uint8_t intensity; 18 | uint8_t alpha; 19 | } ia; 20 | 21 | //--------------------------------------------------------- 22 | // N64 RGBA/IA/I/CI -> intermediate RGBA/IA 23 | //--------------------------------------------------------- 24 | 25 | // N64 raw RGBA16/RGBA32 -> intermediate RGBA 26 | rgba *raw2rgba(const uint8_t *raw, int width, int height, int depth); 27 | 28 | // N64 raw IA1/IA4/IA8/IA16 -> intermediate IA 29 | ia *raw2ia(const uint8_t *raw, int width, int height, int depth); 30 | 31 | // N64 raw I4/I8 -> intermediate IA 32 | ia *raw2i(const uint8_t *raw, int width, int height, int depth); 33 | 34 | // N64 raw CI + palette -> intermediate RGBA 35 | rgba *rawci2rgba(const uint8_t *rawci, const uint8_t *palette, int width, int height, int depth); 36 | 37 | 38 | //--------------------------------------------------------- 39 | // intermediate RGBA/IA -> N64 RGBA/IA/I/CI 40 | // returns length written to 'raw' used or -1 on error 41 | //--------------------------------------------------------- 42 | 43 | // intermediate RGBA -> N64 raw RGBA16/RGBA32 44 | int rgba2raw(uint8_t *raw, const rgba *img, int width, int height, int depth); 45 | 46 | // intermediate IA -> N64 raw IA1/IA4/IA8/IA16 47 | int ia2raw(uint8_t *raw, const ia *img, int width, int height, int depth); 48 | 49 | // intermediate IA -> N64 raw I4/I8 50 | int i2raw(uint8_t *raw, const ia *img, int width, int height, int depth); 51 | 52 | // intermediate RGBA -> N64 raw CI + palette 53 | // TODO 54 | // int rgba2rawci(uint8_t *raw, uint8_t *out_palette, int *pal_len, const rgba *img, int width, int height, int depth); 55 | 56 | 57 | //--------------------------------------------------------- 58 | // intermediate RGBA/IA -> PNG 59 | //--------------------------------------------------------- 60 | 61 | // intermediate RGBA write to PNG file 62 | int rgba2png(const char *png_filename, const rgba *img, int width, int height); 63 | 64 | // intermediate IA write to grayscale PNG file 65 | int ia2png(const char *png_filename, const ia *img, int width, int height); 66 | 67 | 68 | //--------------------------------------------------------- 69 | // PNG -> intermediate RGBA/IA 70 | //--------------------------------------------------------- 71 | 72 | // PNG file -> intermediate RGBA 73 | rgba *png2rgba(const char *png_filename, int *width, int *height); 74 | 75 | // PNG file -> intermediate IA 76 | ia *png2ia(const char *png_filename, int *width, int *height); 77 | 78 | 79 | //--------------------------------------------------------- 80 | // version 81 | //--------------------------------------------------------- 82 | 83 | // get version of underlying graphics reading library 84 | const char *n64graphics_get_read_version(void); 85 | 86 | // get version of underlying graphics writing library 87 | const char *n64graphics_get_write_version(void); 88 | 89 | #endif // N64GRAPHICS_H_ 90 | -------------------------------------------------------------------------------- /tools/n64graphics_ci_dir/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 David Benepe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tools/n64graphics_ci_dir/README.md: -------------------------------------------------------------------------------- 1 | # n64graphics_ci 2 | 3 | Allows you to convert PNG image files to/from N64 CI format. This is temporary until queueRAM adds CI support into his official n64graphics tool. This tool does not process RGBA, IA, or I textures, use n64graphics for those. 4 | 5 | CI4 textures will always assume a 16 color palette is used, and CI8 textures a 256 palette is used. The palette will be generated as a seperate file. The palette file will be named after the CI filename, but postpended with `.pal`. 6 | 7 | ## Libraries Used (All MIT licensed) 8 | 9 | * **Exoquant** by Dennis Ranke, for color reduction. https://github.com/exoticorn/exoquant 10 | * **stb** by Sean Barrett, for loading PNG images. https://github.com/nothings/stb 11 | 12 | ## PNG -> CI4 + Palette 13 | 14 | `./n64graphics_ci -i image.ci4 -g image.png -f ci4` 15 | 16 | ## CI4 + Palette -> 32x32 PNG 17 | 18 | `./n64graphics_ci -e image.ci4 -g image.ci4.png -f ci4 -w 32 -h 32` 19 | 20 | ## PNG -> CI8 + Palette 21 | 22 | `./n64graphics_ci -i image.ci8 -g image.png -f ci8` 23 | 24 | ## CI8 + Palette -> 32x32 PNG 25 | 26 | `./n64graphics_ci -e image.ci8 -g image.ci8.png -f ci8 -w 32 -h 32` 27 | 28 | ## Comparision 29 | ![alt text](https://i.imgur.com/r3PhZp0.png) 30 | -------------------------------------------------------------------------------- /tools/n64graphics_ci_dir/exoquant/exoquant.h: -------------------------------------------------------------------------------- 1 | /* 2 | ExoQuant v0.7 3 | 4 | Copyright (c) 2004 Dennis Ranke 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is furnished to do 11 | so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | /****************************************************************************** 26 | * Usage: 27 | * ------ 28 | * 29 | * exq_data *pExq = exq_init(); // init quantizer (per image) 30 | * exq_feed(pExq, , ); // find palette 32 | * exq_get_palette(pExq, , ); // get palette 33 | * exq_map_image(pExq, , , ); 34 | * or: 35 | * exq_map_image_ordered(pExq, , , , ); 36 | * // map image to palette 37 | * exq_free(pExq); // free memory again 38 | * 39 | * Notes: 40 | * ------ 41 | * 42 | * All 32bpp data (input data and palette data) is considered a byte stream 43 | * of the format: 44 | * R0 G0 B0 A0 R1 G1 B1 A1 ... 45 | * If you want to use a different order, the easiest way to do this is to 46 | * change the SCALE_x constants in expquant.h, as those are the only differences 47 | * between the channels. 48 | * 49 | ******************************************************************************/ 50 | 51 | #ifndef __EXOQUANT_H 52 | #define __EXOQUANT_H 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | /* type definitions */ 59 | typedef double exq_float; 60 | 61 | typedef struct _exq_color 62 | { 63 | exq_float r, g, b, a; 64 | } exq_color; 65 | 66 | typedef struct _exq_histogram 67 | { 68 | exq_color color; 69 | unsigned char ored, ogreen, oblue, oalpha; 70 | int palIndex; 71 | exq_color ditherScale; 72 | int ditherIndex[4]; 73 | int num; 74 | struct _exq_histogram *pNext; 75 | struct _exq_histogram *pNextInHash; 76 | } exq_histogram; 77 | 78 | typedef struct _exq_node 79 | { 80 | exq_color dir, avg; 81 | exq_float vdif; 82 | exq_float err; 83 | int num; 84 | exq_histogram *pHistogram; 85 | exq_histogram *pSplit; 86 | } exq_node; 87 | 88 | #define EXQ_HASH_BITS 16 89 | #define EXQ_HASH_SIZE (1 << (EXQ_HASH_BITS)) 90 | 91 | typedef struct _exq_data 92 | { 93 | exq_histogram *pHash[EXQ_HASH_SIZE]; 94 | exq_node node[256]; 95 | int numColors; 96 | int numBitsPerChannel; 97 | int optimized; 98 | int transparency; 99 | } exq_data; 100 | 101 | /* interface */ 102 | 103 | exq_data *exq_init(); 104 | void exq_no_transparency(exq_data *pExq); 105 | void exq_free(exq_data *pExq); 106 | void exq_feed(exq_data *pExq, unsigned char *pData, 107 | int nPixels); 108 | void exq_quantize(exq_data *pExq, int nColors); 109 | void exq_quantize_hq(exq_data *pExq, int nColors); 110 | void exq_quantize_ex(exq_data *pExq, int nColors, int hq); 111 | exq_float exq_get_mean_error(exq_data *pExq); 112 | void exq_get_palette(exq_data *pExq, unsigned char *pPal, 113 | int nColors); 114 | void exq_set_palette(exq_data *pExq, unsigned char *pPal, 115 | int nColors); 116 | void exq_map_image(exq_data *pExq, int nPixels, 117 | unsigned char *pIn, unsigned char *pOut); 118 | void exq_map_image_ordered(exq_data *pExq, int width, 119 | int height, unsigned char *pIn, 120 | unsigned char *pOut); 121 | void exq_map_image_random(exq_data *pExq, int nPixels, 122 | unsigned char *pIn, unsigned char *pOut); 123 | 124 | /* internal functions */ 125 | 126 | void exq_map_image_dither(exq_data *pExq, int width, 127 | int height, unsigned char *pIn, 128 | unsigned char *pOut, int ordered); 129 | 130 | void exq_sum_node(exq_node *pNode); 131 | void exq_optimize_palette(exq_data *pExp, int iter); 132 | 133 | unsigned char exq_find_nearest_color(exq_data *pExp, exq_color *pColor); 134 | exq_histogram *exq_find_histogram(exq_data *pExp, unsigned char *pCol); 135 | 136 | void exq_sort(exq_histogram **ppHist, 137 | exq_float (*sortfunc)(const exq_histogram *pHist)); 138 | exq_float exq_sort_by_r(const exq_histogram *pHist); 139 | exq_float exq_sort_by_g(const exq_histogram *pHist); 140 | exq_float exq_sort_by_b(const exq_histogram *pHist); 141 | exq_float exq_sort_by_a(const exq_histogram *pHist); 142 | exq_float exq_sort_by_dir(const exq_histogram *pHist); 143 | 144 | extern exq_color exq_sort_dir; 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif 149 | 150 | #endif // __EXOQUANT_H -------------------------------------------------------------------------------- /tools/n64graphics_ci_dir/n64graphics_ci.h: -------------------------------------------------------------------------------- 1 | #ifndef N64GRAPHICS_CI_H_ 2 | #define N64GRAPHICS_CI_H_ 3 | 4 | #include 5 | 6 | // intermediate formats 7 | typedef struct _rgba 8 | { 9 | uint8_t red; 10 | uint8_t green; 11 | uint8_t blue; 12 | uint8_t alpha; 13 | } rgba; 14 | 15 | typedef struct _ia 16 | { 17 | uint8_t intensity; 18 | uint8_t alpha; 19 | } ia; 20 | 21 | // N64 raw RGBA16/RGBA32 -> intermediate RGBA 22 | rgba *raw2rgba(const uint8_t *raw, int width, int height, int depth); 23 | 24 | // N64 raw CI + palette -> intermediate RGBA 25 | rgba *rawci2rgba(const uint8_t *rawci, const uint8_t *palette, int width, int height, int depth); 26 | 27 | // intermediate RGBA -> N64 raw CI + palette 28 | int rgba2rawci(uint8_t *raw, uint8_t *out_palette, int *pal_len, const rgba *img, int width, int height, int depth); 29 | 30 | // PNG file -> intermediate RGBA 31 | rgba *png2rgba(const char *png_filename, int *width, int *height); 32 | 33 | // intermediate RGBA write to PNG file 34 | int rgba2png(const char *png_filename, const rgba *img, int width, int height); 35 | 36 | // get version of underlying graphics reading library 37 | const char *n64graphics_get_read_version(void); 38 | 39 | // get version of underlying graphics writing library 40 | const char *n64graphics_get_write_version(void); 41 | 42 | #endif -------------------------------------------------------------------------------- /tools/n64graphics_ci_dir/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #if defined(_MSC_VER) || defined(__MINGW32__) 9 | #include 10 | #include 11 | #else 12 | #include 13 | #include 14 | #endif 15 | 16 | #include "utils.h" 17 | 18 | // global verbosity setting 19 | int g_verbosity = 0; 20 | 21 | int read_s16_be(unsigned char *buf) 22 | { 23 | unsigned tmp = read_u16_be(buf); 24 | int ret; 25 | if (tmp > 0x7FFF) { 26 | ret = -((int)0x10000 - (int)tmp); 27 | } else { 28 | ret = (int)tmp; 29 | } 30 | return ret; 31 | } 32 | 33 | float read_f32_be(unsigned char *buf) 34 | { 35 | union {uint32_t i; float f;} ret; 36 | ret.i = read_u32_be(buf); 37 | return ret.f; 38 | } 39 | 40 | int is_power2(unsigned int val) 41 | { 42 | while (((val & 1) == 0) && (val > 1)) { 43 | val >>= 1; 44 | } 45 | return (val == 1); 46 | } 47 | 48 | void fprint_hex(FILE *fp, const unsigned char *buf, int length) 49 | { 50 | int i; 51 | for (i = 0; i < length; i++) { 52 | fprint_byte(fp, buf[i]); 53 | fputc(' ', fp); 54 | } 55 | } 56 | 57 | void fprint_hex_source(FILE *fp, const unsigned char *buf, int length) 58 | { 59 | int i; 60 | for (i = 0; i < length; i++) { 61 | if (i > 0) fputs(", ", fp); 62 | fputs("0x", fp); 63 | fprint_byte(fp, buf[i]); 64 | } 65 | } 66 | 67 | void print_hex(const unsigned char *buf, int length) 68 | { 69 | fprint_hex(stdout, buf, length); 70 | } 71 | 72 | void swap_bytes(unsigned char *data, long length) 73 | { 74 | long i; 75 | unsigned char tmp; 76 | for (i = 0; i < length; i += 2) { 77 | tmp = data[i]; 78 | data[i] = data[i+1]; 79 | data[i+1] = tmp; 80 | } 81 | } 82 | 83 | void reverse_endian(unsigned char *data, long length) 84 | { 85 | long i; 86 | unsigned char tmp; 87 | for (i = 0; i < length; i += 4) { 88 | tmp = data[i]; 89 | data[i] = data[i+3]; 90 | data[i+3] = tmp; 91 | tmp = data[i+1]; 92 | data[i+1] = data[i+2]; 93 | data[i+2] = tmp; 94 | } 95 | } 96 | 97 | long filesize(const char *filename) 98 | { 99 | struct stat st; 100 | 101 | if (stat(filename, &st) == 0) { 102 | return st.st_size; 103 | } 104 | 105 | return -1; 106 | } 107 | 108 | void touch_file(const char *filename) 109 | { 110 | int fd; 111 | //fd = open(filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666); 112 | fd = open(filename, O_WRONLY|O_CREAT, 0666); 113 | if (fd >= 0) { 114 | utime(filename, NULL); 115 | close(fd); 116 | } 117 | } 118 | 119 | long read_file(const char *file_name, unsigned char **data) 120 | { 121 | FILE *in; 122 | unsigned char *in_buf = NULL; 123 | long file_size; 124 | long bytes_read; 125 | in = fopen(file_name, "rb"); 126 | if (in == NULL) { 127 | return -1; 128 | } 129 | 130 | // allocate buffer to read from offset to end of file 131 | fseek(in, 0, SEEK_END); 132 | file_size = ftell(in); 133 | 134 | // sanity check 135 | if (file_size > 256*MB) { 136 | return -2; 137 | } 138 | 139 | in_buf = malloc(file_size); 140 | fseek(in, 0, SEEK_SET); 141 | 142 | // read bytes 143 | bytes_read = fread(in_buf, 1, file_size, in); 144 | if (bytes_read != file_size) { 145 | return -3; 146 | } 147 | 148 | fclose(in); 149 | *data = in_buf; 150 | return bytes_read; 151 | } 152 | 153 | long write_file(const char *file_name, unsigned char *data, long length) 154 | { 155 | FILE *out; 156 | long bytes_written; 157 | // open output file 158 | out = fopen(file_name, "wb"); 159 | if (out == NULL) { 160 | perror(file_name); 161 | return -1; 162 | } 163 | bytes_written = fwrite(data, 1, length, out); 164 | fclose(out); 165 | return bytes_written; 166 | } 167 | 168 | void generate_filename(const char *in_name, char *out_name, char *extension) 169 | { 170 | char tmp_name[FILENAME_MAX]; 171 | int len; 172 | int i; 173 | strcpy(tmp_name, in_name); 174 | len = strlen(tmp_name); 175 | for (i = len - 1; i > 0; i--) { 176 | if (tmp_name[i] == '.') { 177 | break; 178 | } 179 | } 180 | if (i <= 0) { 181 | i = len; 182 | } 183 | tmp_name[i] = '\0'; 184 | sprintf(out_name, "%s.%s", tmp_name, extension); 185 | } 186 | 187 | char *basename(const char *name) 188 | { 189 | const char *base = name; 190 | while (*name) { 191 | if (*name++ == '/') { 192 | base = name; 193 | } 194 | } 195 | return (char *)base; 196 | } 197 | 198 | void make_dir(const char *dir_name) 199 | { 200 | struct stat st = {0}; 201 | if (stat(dir_name, &st) == -1) { 202 | mkdir(dir_name, 0755); 203 | } 204 | } 205 | 206 | long copy_file(const char *src_name, const char *dst_name) 207 | { 208 | unsigned char *buf; 209 | long bytes_written; 210 | long bytes_read; 211 | 212 | bytes_read = read_file(src_name, &buf); 213 | 214 | if (bytes_read > 0) { 215 | bytes_written = write_file(dst_name, buf, bytes_read); 216 | if (bytes_written != bytes_read) { 217 | bytes_read = -1; 218 | } 219 | free(buf); 220 | } 221 | 222 | return bytes_read; 223 | } 224 | 225 | void dir_list_ext(const char *dir, const char *extension, dir_list *list) 226 | { 227 | char *pool; 228 | char *pool_ptr; 229 | struct dirent *entry; 230 | DIR *dfd; 231 | int idx; 232 | 233 | dfd = opendir(dir); 234 | if (dfd == NULL) { 235 | ERROR("Can't open '%s'\n", dir); 236 | exit(1); 237 | } 238 | 239 | pool = malloc(FILENAME_MAX * MAX_DIR_FILES); 240 | pool_ptr = pool; 241 | 242 | idx = 0; 243 | while ((entry = readdir(dfd)) != NULL && idx < MAX_DIR_FILES) { 244 | if (!extension || str_ends_with(entry->d_name, extension)) { 245 | sprintf(pool_ptr, "%s/%s", dir, entry->d_name); 246 | list->files[idx] = pool_ptr; 247 | pool_ptr += strlen(pool_ptr) + 1; 248 | idx++; 249 | } 250 | } 251 | list->count = idx; 252 | 253 | closedir(dfd); 254 | } 255 | 256 | void dir_list_free(dir_list *list) 257 | { 258 | // assume first entry in array is allocated 259 | if (list->files[0]) { 260 | free(list->files[0]); 261 | list->files[0] = NULL; 262 | } 263 | } 264 | 265 | int str_ends_with(const char *str, const char *suffix) 266 | { 267 | if (!str || !suffix) { 268 | return 0; 269 | } 270 | size_t len_str = strlen(str); 271 | size_t len_suffix = strlen(suffix); 272 | if (len_suffix > len_str) { 273 | return 0; 274 | } 275 | return (0 == strncmp(str + len_str - len_suffix, suffix, len_suffix)); 276 | } 277 | -------------------------------------------------------------------------------- /tools/n64graphics_ci_dir/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H_ 2 | #define UTILS_H_ 3 | 4 | #include 5 | 6 | // defines 7 | 8 | // printing size_t varies by compiler 9 | #if defined(_MSC_VER) || defined(__MINGW32__) 10 | #define SIZE_T_FORMAT "%Iu" 11 | #else 12 | #define SIZE_T_FORMAT "%zu" 13 | #endif 14 | 15 | #define KB 1024 16 | #define MB (1024 * KB) 17 | 18 | // number of elements in statically declared array 19 | #define DIM(S_ARR_) (sizeof(S_ARR_) / sizeof(S_ARR_[0])) 20 | 21 | #define MIN(A_, B_) ((A_) < (B_) ? (A_) : (B_)) 22 | #define MAX(A_, B_) ((A_) > (B_) ? (A_) : (B_)) 23 | 24 | // align value to N-byte boundary 25 | #define ALIGN(VAL_, ALIGNMENT_) (((VAL_) + ((ALIGNMENT_) - 1)) & ~((ALIGNMENT_) - 1)) 26 | 27 | // read/write u32/16 big/little endian 28 | #define read_u32_be(buf) (unsigned int)(((buf)[0] << 24) + ((buf)[1] << 16) + ((buf)[2] << 8) + ((buf)[3])) 29 | #define read_u32_le(buf) (unsigned int)(((buf)[1] << 24) + ((buf)[0] << 16) + ((buf)[3] << 8) + ((buf)[2])) 30 | #define write_u32_be(buf, val) do { \ 31 | (buf)[0] = ((val) >> 24) & 0xFF; \ 32 | (buf)[1] = ((val) >> 16) & 0xFF; \ 33 | (buf)[2] = ((val) >> 8) & 0xFF; \ 34 | (buf)[3] = (val) & 0xFF; \ 35 | } while(0) 36 | #define read_u16_be(buf) (((buf)[0] << 8) + ((buf)[1])) 37 | #define write_u16_be(buf, val) do { \ 38 | (buf)[0] = ((val) >> 8) & 0xFF; \ 39 | (buf)[1] = ((val)) & 0xFF; \ 40 | } while(0) 41 | 42 | // print nibbles and bytes 43 | #define fprint_nibble(FP, NIB_) fputc((NIB_) < 10 ? ('0' + (NIB_)) : ('A' + (NIB_) - 0xA), FP) 44 | #define fprint_byte(FP, BYTE_) do { \ 45 | fprint_nibble(FP, (BYTE_) >> 4); \ 46 | fprint_nibble(FP, (BYTE_) & 0x0F); \ 47 | } while(0) 48 | #define print_nibble(NIB_) fprint_nibble(stdout, NIB_) 49 | #define print_byte(BYTE_) fprint_byte(stdout, BYTE_) 50 | 51 | // Windows compatibility 52 | #if defined(_MSC_VER) || defined(__MINGW32__) 53 | #include 54 | #define mkdir(DIR_, PERM_) _mkdir(DIR_) 55 | #ifndef strcasecmp 56 | #define strcasecmp(A, B) stricmp(A, B) 57 | #endif 58 | #endif 59 | 60 | // typedefs 61 | 62 | #define MAX_DIR_FILES 128 63 | typedef struct 64 | { 65 | char *files[MAX_DIR_FILES]; 66 | int count; 67 | } dir_list; 68 | 69 | // global verbosity setting 70 | extern int g_verbosity; 71 | 72 | #define ERROR(...) fprintf(stderr, __VA_ARGS__) 73 | #define INFO(...) if (g_verbosity) printf(__VA_ARGS__) 74 | #define INFO_HEX(...) if (g_verbosity) print_hex(__VA_ARGS__) 75 | 76 | // functions 77 | 78 | // convert two bytes in big-endian to signed int 79 | int read_s16_be(unsigned char *buf); 80 | 81 | // convert four bytes in big-endian to float 82 | float read_f32_be(unsigned char *buf); 83 | 84 | // determine if value is power of 2 85 | // returns 1 if val is power of 2, 0 otherwise 86 | int is_power2(unsigned int val); 87 | 88 | // print buffer as hex bytes 89 | // fp: file pointer 90 | // buf: buffer to read bytes from 91 | // length: length of buffer to print 92 | void fprint_hex(FILE *fp, const unsigned char *buf, int length); 93 | void fprint_hex_source(FILE *fp, const unsigned char *buf, int length); 94 | void print_hex(const unsigned char *buf, int length); 95 | 96 | // perform byteswapping to convert from v64 to z64 ordering 97 | void swap_bytes(unsigned char *data, long length); 98 | 99 | // reverse endian to convert from n64 to z64 ordering 100 | void reverse_endian(unsigned char *data, long length); 101 | 102 | // get size of file without opening it; 103 | // returns file size or negative on error 104 | long filesize(const char *file_name); 105 | 106 | // update file timestamp to now, creating it if it doesn't exist 107 | void touch_file(const char *filename); 108 | 109 | // read entire contents of file into buffer 110 | // returns file size or negative on error 111 | long read_file(const char *file_name, unsigned char **data); 112 | 113 | // write buffer to file 114 | // returns number of bytes written out or -1 on failure 115 | long write_file(const char *file_name, unsigned char *data, long length); 116 | 117 | // generate an output file name from input name by replacing file extension 118 | // in_name: input file name 119 | // out_name: buffer to write output name in 120 | // extension: new file extension to use 121 | void generate_filename(const char *in_name, char *out_name, char *extension); 122 | 123 | // extract base filename from file path 124 | // name: path to file 125 | // returns just the file name after the last '/' 126 | char *basename(const char *name); 127 | 128 | // make a directory if it doesn't exist 129 | // dir_name: name of the directory 130 | void make_dir(const char *dir_name); 131 | 132 | // copy a file from src_name to dst_name. will not make directories 133 | // src_name: source file name 134 | // dst_name: destination file name 135 | long copy_file(const char *src_name, const char *dst_name); 136 | 137 | // list a directory, optionally filtering files by extension 138 | // dir: directory to list files in 139 | // extension: extension to filter files by (NULL if no filtering) 140 | // list: output list and count 141 | void dir_list_ext(const char *dir, const char *extension, dir_list *list); 142 | 143 | // free associated date from a directory list 144 | // list: directory list filled in by dir_list_ext() call 145 | void dir_list_free(dir_list *list); 146 | 147 | // determine if a string ends with another string 148 | // str: string to check if ends with 'suffix' 149 | // suffix: string to see if 'str' ends with 150 | // returns 1 if 'str' ends with 'suffix' 151 | int str_ends_with(const char *str, const char *suffix); 152 | 153 | #endif // UTILS_H_ 154 | -------------------------------------------------------------------------------- /tools/patch_libultra_math.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) 4 | { 5 | FILE *f = fopen(argv[1], "r+"); 6 | fseek(f, 0x24, SEEK_SET); 7 | char byte = 0x10; 8 | fwrite(&byte, sizeof(char), 1, f); 9 | fclose(f); 10 | } 11 | -------------------------------------------------------------------------------- /tools/sm64tools.LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2018 queueRAM 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /tools/textconv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "hashtable.h" 10 | #include "utf8.h" 11 | 12 | #define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0])) 13 | 14 | struct CharmapEntry 15 | { 16 | uint32_t unicode[3]; 17 | int length; // length of the unicode array. TODO: use dynamic memory allocation 18 | int bytesCount; 19 | uint8_t bytes[2]; // bytes to convert unicode array to, (e.g. 'A' = 0x0A) 20 | }; 21 | 22 | static struct HashTable *charmap; 23 | 24 | static void fatal_error(const char *msgfmt, ...) 25 | { 26 | va_list args; 27 | 28 | fputs("error: ", stderr); 29 | 30 | va_start(args, msgfmt); 31 | vfprintf(stderr, msgfmt, args); 32 | va_end(args); 33 | 34 | fputc('\n', stderr); 35 | 36 | exit(1); 37 | } 38 | 39 | static void parse_error(const char *filename, int lineNum, const char *msgfmt, ...) 40 | { 41 | va_list args; 42 | 43 | fprintf(stderr, "%s: line %i: ", filename, lineNum); 44 | 45 | va_start(args, msgfmt); 46 | vfprintf(stderr, msgfmt, args); 47 | va_end(args); 48 | 49 | fputc('\n', stderr); 50 | 51 | exit(1); 52 | } 53 | 54 | // Reads the whole file and returns a null-terminated buffer with its contents 55 | void *read_text_file(const char *filename) 56 | { 57 | FILE *file = fopen(filename, "rb"); 58 | uint8_t *buffer; 59 | size_t size; 60 | 61 | if (file == NULL) 62 | fatal_error("failed to open file '%s' for reading: %s", filename, strerror(errno)); 63 | 64 | // get size 65 | fseek(file, 0, SEEK_END); 66 | size = ftell(file); 67 | 68 | // allocate buffer 69 | buffer = malloc(size + 1); 70 | 71 | // read file 72 | fseek(file, 0, SEEK_SET); 73 | if (fread(buffer, size, 1, file) != 1) 74 | fatal_error("error reading from file '%s': %s", filename, strerror(errno)); 75 | 76 | // null-terminate the buffer 77 | buffer[size] = 0; 78 | 79 | fclose(file); 80 | 81 | return buffer; 82 | } 83 | 84 | static char *skip_whitespace(char *str) 85 | { 86 | while (isspace(*str)) 87 | str++; 88 | return str; 89 | } 90 | 91 | // null terminates the current line and returns a pointer to the next line 92 | static char *line_split(char *str) 93 | { 94 | while (*str != '\n') 95 | { 96 | if (*str == 0) 97 | return str; // end of string 98 | str++; 99 | } 100 | *str = 0; // terminate line 101 | return str + 1; 102 | } 103 | 104 | static char *parse_number(const char *str, unsigned int *num) 105 | { 106 | char *endptr; 107 | unsigned int n = strtol(str, &endptr, 0); 108 | 109 | *num = n; 110 | if (endptr > str) 111 | return endptr; 112 | else 113 | return NULL; 114 | } 115 | 116 | static int is_identifier_char(char c) 117 | { 118 | return isalnum(c) || c == '_'; 119 | } 120 | 121 | static int get_escape_char(int c) 122 | { 123 | const uint8_t escapeTable[] = 124 | { 125 | ['a'] = '\a', 126 | ['b'] = '\b', 127 | ['f'] = '\f', 128 | ['n'] = '\n', 129 | ['r'] = '\r', 130 | ['t'] = '\t', 131 | ['v'] = '\v', 132 | ['\\'] = '\\', 133 | ['\''] = '\'', 134 | ['"'] = '"', 135 | }; 136 | 137 | if ((unsigned int)c < ARRAY_COUNT(escapeTable) && escapeTable[c] != 0) 138 | return escapeTable[c]; 139 | else 140 | return 0; 141 | } 142 | 143 | static void read_charmap(const char *filename) 144 | { 145 | char *filedata = read_text_file(filename); 146 | char *line = filedata; 147 | int lineNum = 1; 148 | 149 | while (line[0] != 0) 150 | { 151 | char *nextLine = line_split(line); 152 | 153 | struct CharmapEntry entry; 154 | 155 | line = skip_whitespace(line); 156 | if (line[0] != 0 && line[0] != '#') // ignore empty lines and comments 157 | { 158 | int len = 0; 159 | /* Read Character */ 160 | 161 | // opening quote 162 | if (*line != '\'') 163 | parse_error(filename, lineNum, "expected '"); 164 | line++; 165 | 166 | // perform analysis of charmap entry, we are in the quote 167 | while(1) 168 | { 169 | if(*line == '\'') 170 | { 171 | line++; 172 | break; 173 | } 174 | else if(len == ARRAY_COUNT(entry.unicode)) 175 | { 176 | // TODO: Use dynamic memory allocation so this is unnecessary. 177 | parse_error(filename, lineNum, "string limit exceeded"); 178 | } 179 | else if (*line == '\\') 180 | { 181 | line++; // advance to get the character being escaped 182 | entry.unicode[len] = get_escape_char(*line); 183 | if (entry.unicode[len] == 0) 184 | parse_error(filename, lineNum, "unknown escape sequence \\%c", *line); 185 | line++; // increment again to get past the escape sequence. 186 | } 187 | else 188 | { 189 | line = utf8_decode(line, &entry.unicode[len]); 190 | if (line == NULL) 191 | parse_error(filename, lineNum, "invalid UTF8"); 192 | } 193 | len++; 194 | } 195 | entry.length = len; 196 | 197 | // equals sign 198 | line = skip_whitespace(line); 199 | if (*line != '=') 200 | parse_error(filename, lineNum, "expected = after character \\%c", *line); 201 | line++; 202 | 203 | entry.bytesCount = 0; 204 | 205 | // value 206 | while (1) 207 | { 208 | uint32_t value; 209 | 210 | if (entry.bytesCount >= 2) 211 | parse_error(filename, lineNum, "more than 2 values specified"); 212 | 213 | line = skip_whitespace(line); 214 | 215 | line = parse_number(line, &value); 216 | if (line == NULL) 217 | parse_error(filename, lineNum, "expected number after ="); 218 | if (value > 0xFF) 219 | parse_error(filename, lineNum, "0x%X is larger than 1 byte", value); 220 | 221 | entry.bytes[entry.bytesCount] = value; 222 | entry.bytesCount++; 223 | 224 | line = skip_whitespace(line); 225 | if (*line == 0) 226 | break; 227 | if (*line != ',') 228 | parse_error(filename, lineNum, "junk at end of line"); 229 | line++; 230 | } 231 | 232 | if (hashtable_query(charmap, &entry) != NULL) 233 | parse_error(filename, lineNum, "entry for character already exists"); 234 | hashtable_insert(charmap, &entry); 235 | } 236 | 237 | line = nextLine; 238 | lineNum++; 239 | } 240 | 241 | free(filedata); 242 | } 243 | 244 | static int count_line_num(const char *start, const char *pos) 245 | { 246 | const char *c; 247 | int lineNum = 1; 248 | 249 | for (c = start; c < pos; c++) 250 | { 251 | if (*c == '\n') 252 | lineNum++; 253 | } 254 | return lineNum; 255 | } 256 | 257 | static char *convert_string(char *pos, FILE *fout, const char *inputFileName, char *start) 258 | { 259 | int hasString = 0; 260 | 261 | while (1) 262 | { 263 | pos = skip_whitespace(pos); 264 | if (*pos == ')') 265 | { 266 | if (hasString) 267 | break; 268 | else 269 | parse_error(inputFileName, count_line_num(start, pos), "expected quoted string after '_('"); 270 | } 271 | else if (*pos != '"') 272 | parse_error(inputFileName, count_line_num(start, pos), "unexpected character '%c'", *pos); 273 | pos++; 274 | 275 | hasString = 1; 276 | 277 | // convert quoted string 278 | while (*pos != '"') 279 | { 280 | struct CharmapEntry input; 281 | struct CharmapEntry *last_valid_entry = NULL; 282 | struct CharmapEntry *entry; 283 | int i, c; 284 | int length = 0; 285 | char* last_valid_pos = NULL; 286 | 287 | // safely erase the unicode area before use 288 | memset(input.unicode, 0, sizeof (input.unicode)); 289 | input.length = 0; 290 | 291 | // Find a charmap entry of longest length possible starting from this position 292 | while (*pos != '"') 293 | { 294 | if (length == ARRAY_COUNT(entry->unicode)) 295 | { 296 | // Stop searching after length 3; we only support strings of lengths up 297 | // to that right now. 298 | break; 299 | } 300 | 301 | if (*pos == 0) 302 | parse_error(inputFileName, count_line_num(start, pos), "EOF in string literal"); 303 | if (*pos == '\\') 304 | { 305 | pos++; 306 | c = get_escape_char(*pos); 307 | if (c == 0) 308 | parse_error(inputFileName, count_line_num(start, pos), "unknown escape sequence \\%c", *pos); 309 | input.unicode[length] = c; 310 | pos++; 311 | } 312 | else 313 | { 314 | pos = utf8_decode(pos, &input.unicode[length]); 315 | if (pos == NULL) 316 | parse_error(inputFileName, count_line_num(start, pos), "invalid unicode encountered in file"); 317 | } 318 | length++; 319 | input.length = length; 320 | 321 | entry = hashtable_query(charmap, &input); 322 | if (entry != NULL) 323 | { 324 | last_valid_entry = entry; 325 | last_valid_pos = pos; 326 | } 327 | } 328 | 329 | entry = last_valid_entry; 330 | pos = last_valid_pos; 331 | if (entry == NULL) 332 | parse_error(inputFileName, count_line_num(start, pos), "no charmap entry for U+%X", input.unicode[0]); 333 | for (i = 0; i < entry->bytesCount; i++) 334 | fprintf(fout, "0x%02X,", entry->bytes[i]); 335 | } 336 | pos++; // skip over closing '"' 337 | } 338 | pos++; // skip over closing ')' 339 | fputs("0xFF", fout); 340 | return pos; 341 | } 342 | 343 | static void convert_file(const char *infilename, const char *outfilename) 344 | { 345 | char *in = read_text_file(infilename); 346 | FILE *fout = fopen(outfilename, "wb"); 347 | 348 | if (fout == NULL) 349 | fatal_error("failed to open file '%s' for writing: %s", strerror(errno)); 350 | 351 | char *start = in; 352 | char *end = in; 353 | char *pos = in; 354 | 355 | while (1) 356 | { 357 | if (*pos == 0) // end of file 358 | goto eof; 359 | 360 | // check for comment 361 | if (*pos == '/') 362 | { 363 | pos++; 364 | // skip over // comment 365 | if (*pos == '/') 366 | { 367 | pos++; 368 | // skip over next newline 369 | while (*pos != '\n') 370 | { 371 | if (*pos == 0) 372 | goto eof; 373 | pos++; 374 | } 375 | pos++; 376 | } 377 | // skip over /* */ comment 378 | else if (*pos == '*') 379 | { 380 | pos++; 381 | while (*pos != '*' && pos[1] != '/') 382 | { 383 | if (*pos == 0) 384 | goto eof; 385 | pos++; 386 | } 387 | pos += 2; 388 | } 389 | } 390 | // skip over normal string literal 391 | else if (*pos == '"') 392 | { 393 | pos++; 394 | while (*pos != '"') 395 | { 396 | if (*pos == 0) 397 | goto eof; 398 | if (*pos == '\\') 399 | pos++; 400 | pos++; 401 | } 402 | pos++; 403 | } 404 | // check for _( sequence 405 | else if (*pos == '_' && (pos == in || !is_identifier_char(pos[-1]))) 406 | { 407 | end = pos; 408 | pos++; 409 | if (*pos == '(') 410 | { 411 | pos++; 412 | fwrite(start, end - start, 1, fout); 413 | pos = convert_string(pos, fout, infilename, in); 414 | start = pos; 415 | } 416 | } 417 | else 418 | { 419 | pos++; 420 | } 421 | } 422 | 423 | eof: 424 | fwrite(start, pos - start, 1, fout); 425 | fclose(fout); 426 | free(in); 427 | } 428 | 429 | static unsigned int charmap_hash(const void *value) 430 | { 431 | const struct CharmapEntry* entry = value; 432 | unsigned int ret = 0; 433 | for (int i = 0; i < entry->length; i++) 434 | ret = ret * 17 + entry->unicode[i]; 435 | return ret; 436 | } 437 | 438 | static int charmap_cmp(const void *a, const void *b) 439 | { 440 | const struct CharmapEntry *ea = a; 441 | const struct CharmapEntry *eb = b; 442 | if (ea->length != eb->length) 443 | return 0; 444 | for(int i = 0; i < ea->length; i++) 445 | if(ea->unicode[i] != eb->unicode[i]) 446 | return 0; 447 | return 1; 448 | } 449 | 450 | static void usage(const char *execName) 451 | { 452 | fprintf(stderr, "Usage: %s CHARMAP INPUT OUTPUT\n", execName); 453 | } 454 | 455 | int main(int argc, char **argv) 456 | { 457 | if (argc != 4) 458 | { 459 | usage(argv[0]); 460 | return 1; 461 | } 462 | 463 | charmap = hashtable_new(charmap_hash, charmap_cmp, 256, sizeof(struct CharmapEntry)); 464 | 465 | read_charmap(argv[1]); 466 | convert_file(argv[2], argv[3]); 467 | 468 | hashtable_free(charmap); 469 | 470 | return 0; 471 | } 472 | -------------------------------------------------------------------------------- /tools/utf8.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "utf8.h" 5 | 6 | /* Copyright (c) 2008-2009 Bjoern Hoehrmann 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | * SOFTWARE. 25 | */ 26 | 27 | #define UTF8_ACCEPT 0 28 | #define UTF8_REJECT 1 29 | 30 | static const uint8_t utf8d[] = { 31 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f 32 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f 33 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f 34 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f 35 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f 36 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf 37 | 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df 38 | 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef 39 | 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff 40 | 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 41 | 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 42 | 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 43 | 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 44 | 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 45 | }; 46 | 47 | static uint32_t 48 | decode(uint32_t* state, uint32_t* codep, uint32_t byte) { 49 | uint32_t type = utf8d[byte]; 50 | 51 | *codep = (*state != UTF8_ACCEPT) ? 52 | (byte & 0x3fu) | (*codep << 6) : 53 | (0xff >> type) & (byte); 54 | 55 | *state = utf8d[256 + *state*16 + type]; 56 | return *state; 57 | } 58 | 59 | char *utf8_decode(char *str, uint32_t *codep) 60 | { 61 | uint32_t state = UTF8_ACCEPT; 62 | 63 | *codep = 0; 64 | while (*str != 0) 65 | { 66 | int result = decode(&state, codep, (unsigned char)*str); 67 | str++; 68 | if (result == UTF8_ACCEPT) 69 | return str; 70 | if (result == UTF8_REJECT) 71 | return NULL; 72 | } 73 | return NULL; 74 | } 75 | -------------------------------------------------------------------------------- /tools/utf8.h: -------------------------------------------------------------------------------- 1 | #ifndef UTF8_H_ 2 | #define UTF8_H_ 3 | 4 | char *utf8_decode(char *str, uint32_t *codep); 5 | 6 | #endif // UTF8_H_ 7 | -------------------------------------------------------------------------------- /tools/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #if defined(_MSC_VER) || defined(__MINGW32__) 9 | #include 10 | #include 11 | #else 12 | #include 13 | #include 14 | #endif 15 | 16 | #include "utils.h" 17 | 18 | // global verbosity setting 19 | int g_verbosity = 0; 20 | 21 | int read_s16_be(unsigned char *buf) 22 | { 23 | unsigned tmp = read_u16_be(buf); 24 | int ret; 25 | if (tmp > 0x7FFF) { 26 | ret = -((int)0x10000 - (int)tmp); 27 | } else { 28 | ret = (int)tmp; 29 | } 30 | return ret; 31 | } 32 | 33 | float read_f32_be(unsigned char *buf) 34 | { 35 | union {uint32_t i; float f;} ret; 36 | ret.i = read_u32_be(buf); 37 | return ret.f; 38 | } 39 | 40 | int is_power2(unsigned int val) 41 | { 42 | while (((val & 1) == 0) && (val > 1)) { 43 | val >>= 1; 44 | } 45 | return (val == 1); 46 | } 47 | 48 | void fprint_hex(FILE *fp, const unsigned char *buf, int length) 49 | { 50 | int i; 51 | for (i = 0; i < length; i++) { 52 | fprint_byte(fp, buf[i]); 53 | fputc(' ', fp); 54 | } 55 | } 56 | 57 | void fprint_hex_source(FILE *fp, const unsigned char *buf, int length) 58 | { 59 | int i; 60 | for (i = 0; i < length; i++) { 61 | if (i > 0) fputs(", ", fp); 62 | fputs("0x", fp); 63 | fprint_byte(fp, buf[i]); 64 | } 65 | } 66 | 67 | void print_hex(const unsigned char *buf, int length) 68 | { 69 | fprint_hex(stdout, buf, length); 70 | } 71 | 72 | void swap_bytes(unsigned char *data, long length) 73 | { 74 | long i; 75 | unsigned char tmp; 76 | for (i = 0; i < length; i += 2) { 77 | tmp = data[i]; 78 | data[i] = data[i+1]; 79 | data[i+1] = tmp; 80 | } 81 | } 82 | 83 | void reverse_endian(unsigned char *data, long length) 84 | { 85 | long i; 86 | unsigned char tmp; 87 | for (i = 0; i < length; i += 4) { 88 | tmp = data[i]; 89 | data[i] = data[i+3]; 90 | data[i+3] = tmp; 91 | tmp = data[i+1]; 92 | data[i+1] = data[i+2]; 93 | data[i+2] = tmp; 94 | } 95 | } 96 | 97 | long filesize(const char *filename) 98 | { 99 | struct stat st; 100 | 101 | if (stat(filename, &st) == 0) { 102 | return st.st_size; 103 | } 104 | 105 | return -1; 106 | } 107 | 108 | void touch_file(const char *filename) 109 | { 110 | int fd; 111 | //fd = open(filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666); 112 | fd = open(filename, O_WRONLY|O_CREAT, 0666); 113 | if (fd >= 0) { 114 | utime(filename, NULL); 115 | close(fd); 116 | } 117 | } 118 | 119 | long read_file(const char *file_name, unsigned char **data) 120 | { 121 | FILE *in; 122 | unsigned char *in_buf = NULL; 123 | long file_size; 124 | long bytes_read; 125 | in = fopen(file_name, "rb"); 126 | if (in == NULL) { 127 | return -1; 128 | } 129 | 130 | // allocate buffer to read from offset to end of file 131 | fseek(in, 0, SEEK_END); 132 | file_size = ftell(in); 133 | 134 | // sanity check 135 | if (file_size > 256*MB) { 136 | return -2; 137 | } 138 | 139 | in_buf = malloc(file_size); 140 | fseek(in, 0, SEEK_SET); 141 | 142 | // read bytes 143 | bytes_read = fread(in_buf, 1, file_size, in); 144 | if (bytes_read != file_size) { 145 | return -3; 146 | } 147 | 148 | fclose(in); 149 | *data = in_buf; 150 | return bytes_read; 151 | } 152 | 153 | long write_file(const char *file_name, unsigned char *data, long length) 154 | { 155 | FILE *out; 156 | long bytes_written; 157 | // open output file 158 | out = fopen(file_name, "wb"); 159 | if (out == NULL) { 160 | perror(file_name); 161 | return -1; 162 | } 163 | bytes_written = fwrite(data, 1, length, out); 164 | fclose(out); 165 | return bytes_written; 166 | } 167 | 168 | void generate_filename(const char *in_name, char *out_name, char *extension) 169 | { 170 | char tmp_name[FILENAME_MAX]; 171 | int len; 172 | int i; 173 | strcpy(tmp_name, in_name); 174 | len = strlen(tmp_name); 175 | for (i = len - 1; i > 0; i--) { 176 | if (tmp_name[i] == '.') { 177 | break; 178 | } 179 | } 180 | if (i <= 0) { 181 | i = len; 182 | } 183 | tmp_name[i] = '\0'; 184 | sprintf(out_name, "%s.%s", tmp_name, extension); 185 | } 186 | 187 | char *basename(const char *name) 188 | { 189 | const char *base = name; 190 | while (*name) { 191 | if (*name++ == '/') { 192 | base = name; 193 | } 194 | } 195 | return (char *)base; 196 | } 197 | 198 | void make_dir(const char *dir_name) 199 | { 200 | struct stat st = {0}; 201 | if (stat(dir_name, &st) == -1) { 202 | mkdir(dir_name, 0755); 203 | } 204 | } 205 | 206 | long copy_file(const char *src_name, const char *dst_name) 207 | { 208 | unsigned char *buf; 209 | long bytes_written; 210 | long bytes_read; 211 | 212 | bytes_read = read_file(src_name, &buf); 213 | 214 | if (bytes_read > 0) { 215 | bytes_written = write_file(dst_name, buf, bytes_read); 216 | if (bytes_written != bytes_read) { 217 | bytes_read = -1; 218 | } 219 | free(buf); 220 | } 221 | 222 | return bytes_read; 223 | } 224 | 225 | void dir_list_ext(const char *dir, const char *extension, dir_list *list) 226 | { 227 | char *pool; 228 | char *pool_ptr; 229 | struct dirent *entry; 230 | DIR *dfd; 231 | int idx; 232 | 233 | dfd = opendir(dir); 234 | if (dfd == NULL) { 235 | ERROR("Can't open '%s'\n", dir); 236 | exit(1); 237 | } 238 | 239 | pool = malloc(FILENAME_MAX * MAX_DIR_FILES); 240 | pool_ptr = pool; 241 | 242 | idx = 0; 243 | while ((entry = readdir(dfd)) != NULL && idx < MAX_DIR_FILES) { 244 | if (!extension || str_ends_with(entry->d_name, extension)) { 245 | sprintf(pool_ptr, "%s/%s", dir, entry->d_name); 246 | list->files[idx] = pool_ptr; 247 | pool_ptr += strlen(pool_ptr) + 1; 248 | idx++; 249 | } 250 | } 251 | list->count = idx; 252 | 253 | closedir(dfd); 254 | } 255 | 256 | void dir_list_free(dir_list *list) 257 | { 258 | // assume first entry in array is allocated 259 | if (list->files[0]) { 260 | free(list->files[0]); 261 | list->files[0] = NULL; 262 | } 263 | } 264 | 265 | int str_ends_with(const char *str, const char *suffix) 266 | { 267 | if (!str || !suffix) { 268 | return 0; 269 | } 270 | size_t len_str = strlen(str); 271 | size_t len_suffix = strlen(suffix); 272 | if (len_suffix > len_str) { 273 | return 0; 274 | } 275 | return (0 == strncmp(str + len_str - len_suffix, suffix, len_suffix)); 276 | } 277 | -------------------------------------------------------------------------------- /tools/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H_ 2 | #define UTILS_H_ 3 | 4 | #include 5 | 6 | // defines 7 | 8 | // printing size_t varies by compiler 9 | #if defined(_MSC_VER) || defined(__MINGW32__) 10 | #define SIZE_T_FORMAT "%Iu" 11 | #else 12 | #define SIZE_T_FORMAT "%zu" 13 | #endif 14 | 15 | #define KB 1024 16 | #define MB (1024 * KB) 17 | 18 | // number of elements in statically declared array 19 | #define DIM(S_ARR_) (sizeof(S_ARR_) / sizeof(S_ARR_[0])) 20 | 21 | #define MIN(A_, B_) ((A_) < (B_) ? (A_) : (B_)) 22 | #define MAX(A_, B_) ((A_) > (B_) ? (A_) : (B_)) 23 | 24 | // align value to N-byte boundary 25 | #define ALIGN(VAL_, ALIGNMENT_) (((VAL_) + ((ALIGNMENT_) - 1)) & ~((ALIGNMENT_) - 1)) 26 | 27 | // read/write u32/16 big/little endian 28 | #define read_u32_be(buf) (unsigned int)(((buf)[0] << 24) + ((buf)[1] << 16) + ((buf)[2] << 8) + ((buf)[3])) 29 | #define read_u32_le(buf) (unsigned int)(((buf)[1] << 24) + ((buf)[0] << 16) + ((buf)[3] << 8) + ((buf)[2])) 30 | #define write_u32_be(buf, val) do { \ 31 | (buf)[0] = ((val) >> 24) & 0xFF; \ 32 | (buf)[1] = ((val) >> 16) & 0xFF; \ 33 | (buf)[2] = ((val) >> 8) & 0xFF; \ 34 | (buf)[3] = (val) & 0xFF; \ 35 | } while(0) 36 | #define read_u16_be(buf) (((buf)[0] << 8) + ((buf)[1])) 37 | #define write_u16_be(buf, val) do { \ 38 | (buf)[0] = ((val) >> 8) & 0xFF; \ 39 | (buf)[1] = ((val)) & 0xFF; \ 40 | } while(0) 41 | 42 | // print nibbles and bytes 43 | #define fprint_nibble(FP, NIB_) fputc((NIB_) < 10 ? ('0' + (NIB_)) : ('A' + (NIB_) - 0xA), FP) 44 | #define fprint_byte(FP, BYTE_) do { \ 45 | fprint_nibble(FP, (BYTE_) >> 4); \ 46 | fprint_nibble(FP, (BYTE_) & 0x0F); \ 47 | } while(0) 48 | #define print_nibble(NIB_) fprint_nibble(stdout, NIB_) 49 | #define print_byte(BYTE_) fprint_byte(stdout, BYTE_) 50 | 51 | // Windows compatibility 52 | #if defined(_MSC_VER) || defined(__MINGW32__) 53 | #include 54 | #define mkdir(DIR_, PERM_) _mkdir(DIR_) 55 | #ifndef strcasecmp 56 | #define strcasecmp(A, B) stricmp(A, B) 57 | #endif 58 | #endif 59 | 60 | // typedefs 61 | 62 | #define MAX_DIR_FILES 128 63 | typedef struct 64 | { 65 | char *files[MAX_DIR_FILES]; 66 | int count; 67 | } dir_list; 68 | 69 | // global verbosity setting 70 | extern int g_verbosity; 71 | 72 | #define ERROR(...) fprintf(stderr, __VA_ARGS__) 73 | #define INFO(...) if (g_verbosity) printf(__VA_ARGS__) 74 | #define INFO_HEX(...) if (g_verbosity) print_hex(__VA_ARGS__) 75 | 76 | // functions 77 | 78 | // convert two bytes in big-endian to signed int 79 | int read_s16_be(unsigned char *buf); 80 | 81 | // convert four bytes in big-endian to float 82 | float read_f32_be(unsigned char *buf); 83 | 84 | // determine if value is power of 2 85 | // returns 1 if val is power of 2, 0 otherwise 86 | int is_power2(unsigned int val); 87 | 88 | // print buffer as hex bytes 89 | // fp: file pointer 90 | // buf: buffer to read bytes from 91 | // length: length of buffer to print 92 | void fprint_hex(FILE *fp, const unsigned char *buf, int length); 93 | void fprint_hex_source(FILE *fp, const unsigned char *buf, int length); 94 | void print_hex(const unsigned char *buf, int length); 95 | 96 | // perform byteswapping to convert from v64 to z64 ordering 97 | void swap_bytes(unsigned char *data, long length); 98 | 99 | // reverse endian to convert from n64 to z64 ordering 100 | void reverse_endian(unsigned char *data, long length); 101 | 102 | // get size of file without opening it; 103 | // returns file size or negative on error 104 | long filesize(const char *file_name); 105 | 106 | // update file timestamp to now, creating it if it doesn't exist 107 | void touch_file(const char *filename); 108 | 109 | // read entire contents of file into buffer 110 | // returns file size or negative on error 111 | long read_file(const char *file_name, unsigned char **data); 112 | 113 | // write buffer to file 114 | // returns number of bytes written out or -1 on failure 115 | long write_file(const char *file_name, unsigned char *data, long length); 116 | 117 | // generate an output file name from input name by replacing file extension 118 | // in_name: input file name 119 | // out_name: buffer to write output name in 120 | // extension: new file extension to use 121 | void generate_filename(const char *in_name, char *out_name, char *extension); 122 | 123 | // extract base filename from file path 124 | // name: path to file 125 | // returns just the file name after the last '/' 126 | char *basename(const char *name); 127 | 128 | // make a directory if it doesn't exist 129 | // dir_name: name of the directory 130 | void make_dir(const char *dir_name); 131 | 132 | // copy a file from src_name to dst_name. will not make directories 133 | // src_name: source file name 134 | // dst_name: destination file name 135 | long copy_file(const char *src_name, const char *dst_name); 136 | 137 | // list a directory, optionally filtering files by extension 138 | // dir: directory to list files in 139 | // extension: extension to filter files by (NULL if no filtering) 140 | // list: output list and count 141 | void dir_list_ext(const char *dir, const char *extension, dir_list *list); 142 | 143 | // free associated date from a directory list 144 | // list: directory list filled in by dir_list_ext() call 145 | void dir_list_free(dir_list *list); 146 | 147 | // determine if a string ends with another string 148 | // str: string to check if ends with 'suffix' 149 | // suffix: string to see if 'str' ends with 150 | // returns 1 if 'str' ends with 'suffix' 151 | int str_ends_with(const char *str, const char *suffix); 152 | 153 | #endif // UTILS_H_ 154 | --------------------------------------------------------------------------------