blob: d124399bccff672684f01f3d65c8e953596ab470 [file]
#pragma once
#include <vector>
#include <array>
#include <map>
#include <string>
#include <cstdint>
#include <cstdarg>
#include "byte-killer.hpp"
namespace another_world {
constexpr uint32_t HEAP_SIZE = 100000;
constexpr uint16_t REGISTER_COUNT = 256;
constexpr uint16_t THREAD_COUNT = 64;
extern uint16_t read_uint16_bigendian(const void* p);
extern uint32_t read_uint32_bigendian(const void* p);
extern bool (*read_file)(std::string filename, uint32_t offset, uint32_t length, char* buffer);
extern void (*debug)(const char *fmt, ...);
extern void (*update_screen)(uint8_t *buffer);
extern void (*set_palette)(uint16_t* palette);
extern void (*debug_display_update)();
void init_resources();
void load_chapter_resources();
void load_needed_resources();
// three buffers for 320 x 200 (4 bits per pixel)
extern uint8_t vram0[320 * 200 / 2];
extern uint8_t vram1[320 * 200 / 2];
extern uint8_t vram2[320 * 200 / 2];
extern uint8_t vram3[320 * 200 / 2];
extern uint8_t* vram[4];
// each chapter of the game has a set of fixed resources related to it.
// these include the vm code, video 1, video 2, and palette
struct ChapterResources {
uint8_t palette;
uint8_t code;
uint8_t background;
uint8_t characters;
};
struct Input {
bool up, down, left, right, action;
};
extern Input input;
struct Point {
int16_t x, y;
};
struct Rect {
int16_t x, y, w, h;
};
struct Resource {
enum class State { NOT_NEEDED = 0, LOADED = 1, NEEDS_LOADING = 2, END_OF_MEMLIST = 0xff };
enum class Type { SOUND = 0, MUSIC = 1, IMAGE = 2, PALETTE = 3, BYTECODE = 4, POLYGON = 5, BANK = 6 };
State state;
Type type;
uint8_t bank_id;
uint32_t bank_offset;
uint16_t packed_size;
uint16_t size;
uint8_t *data;
bool load(uint8_t* destination);
};
struct Thread {
uint16_t pc;
bool paused;
};
extern std::vector<Resource*> resources;
extern uint32_t resource_heap_offset;
extern uint8_t resource_heap[HEAP_SIZE];
extern ChapterResources chapter_resources[10];
struct VirtualMachine {
uint32_t ticks = 0;
uint8_t chapter_id;
std::array<Thread, THREAD_COUNT> threads;
int16_t registers[REGISTER_COUNT];
std::vector<uint16_t> call_stack;
Resource *palette;
Resource *code;
Resource *background;
Resource *characters;
uint8_t *working_vram = vram[0];
uint8_t *visible_vram = vram[0];
void init();
void initialise_chapter(uint16_t id);
void execute_threads();
void process_input();
uint8_t fetch_byte(uint16_t* pc);
uint8_t fetch_byte(uint8_t* b, uint32_t* c);
uint16_t fetch_word(uint16_t* pc);
uint16_t fetch_word(uint8_t* b, uint32_t* c);
uint8_t* get_vram_from_id(uint8_t id);
void draw_shape(uint8_t color, Point pos, int16_t zoom, uint8_t* buffer, uint32_t *offset);
void draw_shape_group(uint8_t color, Point pos, int16_t zoom, uint8_t* buffer, uint32_t* offset);
void draw_polygon(uint8_t color, Point pos, int16_t zoom, uint8_t* buffer, uint32_t *offset);
void polygon(uint8_t* target, uint8_t color, Point* points, uint8_t point_count);
void point(uint8_t* target, uint8_t color, Point* point);
};
const std::string opcode_names[29] = {
"movi", // 0x00 movi d0, #1234
"mov", // 0x01 mov d0, d1
"add", // 0x02 add d0, d1
"addi", // 0x03 addi d0, #1234
"call", // 0x04 call #1234
"ret", // 0x05 ret
"brk", // 0x06 brk
"jmp", // 0x07 jmp #1234
"svec", // 0x08 svec #12, #1234
"djnz", // 0x09 djnz d0, #1234
"cjmp", // 0x0a cjmp #12, d0, d1 or #1234, #1234
"pal", // 0x0b pal #12, #12
"???", // 0x0c ??? #12, #12, #12
"setws", // 0x0d setws #12
"vclr", // 0x0e vclr #12, #12
"vcpy", // 0x0f vcpy #12, #12
"vshw", // 0x10 vshw #12
"kill", // 0x11 kill
"text", // 0x12 text #1234, #12, #12, #12
"sub", // 0x13 sub d0, d1
"andi", // 0x14 andi d0, #1234
"ori", // 0x15 ori d0, #1234
"shli", // 0x16 shli d0, #1234
"shri", // 0x17 shri d0, #1234
"snd", // 0x18 snd #1234, #12, #12, #12
"load", // 0x19 load #1234
"music" // 0x1a music #1234, #1234, #12
};
/*
const std::map<uint16_t, std::string> string_table = {
{ 0x001, "P E A N U T 3000" },
{ 0x002, "Copyright } 1990 Peanut Computer, Inc.\nAll rights reserved.\n\nCDOS Version 5.01" },
{ 0x003, "2" },
{ 0x004, "3" },
{ 0x005, "." },
{ 0x006, "A" },
{ 0x007, "@" },
{ 0x008, "PEANUT 3000" },
{ 0x00A, "R" },
{ 0x00B, "U" },
{ 0x00C, "N" },
{ 0x00D, "P" },
{ 0x00E, "R" },
{ 0x00F, "O" },
{ 0x010, "J" },
{ 0x011, "E" },
{ 0x012, "C" },
{ 0x013, "T" },
{ 0x014, "Shield 9A.5f Ok" },
{ 0x015, "Flux % 5.0177 Ok" },
{ 0x016, "CDI Vector ok" },
{ 0x017, " %%%ddd ok" },
{ 0x018, "Race-Track ok" },
{ 0x019, "SYNCHROTRON" },
{ 0x01A, "E: 23%\ng: .005\n\nRK: 77.2L\n\nopt: g+\n\n Shield:\n1: OFF\n2: ON\n3: ON\n\nP~: 1\n" },
{ 0x01B, "ON" },
{ 0x01C, "-" },
{ 0x021, "|" },
{ 0x022, "--- Theoretical study ---" },
{ 0x023, " THE EXPERIMENT WILL BEGIN IN SECONDS" },
{ 0x024, " 20" },
{ 0x025, " 19" },
{ 0x026, " 18" },
{ 0x027, " 4" },
{ 0x028, " 3" },
{ 0x029, " 2" },
{ 0x02A, " 1" },
{ 0x02B, " 0" },
{ 0x02C, "L E T ' S G O" },
{ 0x031, "- Phase 0:\nINJECTION of particles\ninto synchrotron" },
{ 0x032, "- Phase 1:\nParticle ACCELERATION." },
{ 0x033, "- Phase 2:\nEJECTION of particles\non the shield." },
{ 0x034, "A N A L Y S I S" },
{ 0x035, "- RESULT:\nProbability of creating:\n ANTIMATTER: 91.V %\n NEUTRINO 27: 0.04 %\n NEUTRINO 424: 18 %\n" },
{ 0x036, " Practical verification Y/N ?" },
{ 0x037, "SURE ?" },
{ 0x038, "MODIFICATION OF PARAMETERS\nRELATING TO PARTICLE\nACCELERATOR (SYNCHROTRON)." },
{ 0x039, " RUN EXPERIMENT ?" },
{ 0x03C, "t---t" },
{ 0x03D, "000 ~" },
{ 0x03E, ".20x14dd" },
{ 0x03F, "gj5r5r" },
{ 0x040, "tilgor 25%" },
{ 0x041, "12% 33% checked" },
{ 0x042, "D=4.2158005584" },
{ 0x043, "d=10.00001" },
{ 0x044, "+" },
{ 0x045, "*" },
{ 0x046, "% 304" },
{ 0x047, "gurgle 21" },
{ 0x048, "{{{{" },
{ 0x049, "Delphine Software" },
{ 0x04A, "By Eric Chahi" },
{ 0x04B, " 5" },
{ 0x04C, " 17" },
{ 0x12C, "0" },
{ 0x12D, "1" },
{ 0x12E, "2" },
{ 0x12F, "3" },
{ 0x130, "4" },
{ 0x131, "5" },
{ 0x132, "6" },
{ 0x133, "7" },
{ 0x134, "8" },
{ 0x135, "9" },
{ 0x136, "A" },
{ 0x137, "B" },
{ 0x138, "C" },
{ 0x139, "D" },
{ 0x13A, "E" },
{ 0x13B, "F" },
{ 0x13C, " ACCESS CODE:" },
{ 0x13D, "PRESS BUTTON OR RETURN TO CONTINUE" },
{ 0x13E, " ENTER ACCESS CODE" },
{ 0x13F, " INVALID PASSWORD !" },
{ 0x140, "ANNULER" },
{ 0x141, " INSERT DISK ?\n\n\n\n\n\n\n\n\nPRESS ANY KEY TO CONTINUE" },
{ 0x142, " SELECT SYMBOLS CORRESPONDING TO\n THE POSITION\n ON THE CODE WHEEL" },
{ 0x143, " LOADING..." },
{ 0x144, " ERROR" },
{ 0x15E, "LDKD" },
{ 0x15F, "HTDC" },
{ 0x160, "CLLD" },
{ 0x161, "FXLC" },
{ 0x162, "KRFK" },
{ 0x163, "XDDJ" },
{ 0x164, "LBKG" },
{ 0x165, "KLFB" },
{ 0x166, "TTCT" },
{ 0x167, "DDRX" },
{ 0x168, "TBHK" },
{ 0x169, "BRTD" },
{ 0x16A, "CKJL" },
{ 0x16B, "LFCK" },
{ 0x16C, "BFLX" },
{ 0x16D, "XJRT" },
{ 0x16E, "HRTB" },
{ 0x16F, "HBHK" },
{ 0x170, "JCGB" },
{ 0x171, "HHFL" },
{ 0x172, "TFBB" },
{ 0x173, "TXHF" },
{ 0x174, "JHJL" },
{ 0x181, " BY" },
{ 0x182, "ERIC CHAHI" },
{ 0x183, " MUSIC AND SOUND EFFECTS" },
{ 0x184, " " },
{ 0x185, "JEAN-FRANCOIS FREITAS" },
{ 0x186, "IBM PC VERSION" },
{ 0x187, " BY" },
{ 0x188, " DANIEL MORAIS" },
{ 0x18B, " THEN PRESS FIRE" },
{ 0x18C, " PUT THE PADDLE ON THE UPPER LEFT CORNER" },
{ 0x18D, "PUT THE PADDLE IN CENTRAL POSITION" },
{ 0x18E, "PUT THE PADDLE ON THE LOWER RIGHT CORNER" },
{ 0x258, " Designed by ..... Eric Chahi" },
{ 0x259, " Programmed by...... Eric Chahi" },
{ 0x25A, " Artwork ......... Eric Chahi" },
{ 0x25B, "Music by ........ Jean-francois Freitas" },
{ 0x25C, " Sound effects" },
{ 0x25D, " Jean-Francois Freitas\n Eric Chahi" },
{ 0x263, " Thanks To" },
{ 0x264, " Jesus Martinez\n\n Daniel Morais\n\n Frederic Savoir\n\n Cecile Chahi\n\n Philippe Delamarre\n\n Philippe Ulrich\n\nSebastien Berthet\n\nPierre Gousseau" },
{ 0x265, "Now Go Out Of This World" },
{ 0x190, "Good evening professor." },
{ 0x191, "I see you have driven here in your\nFerrari." },
{ 0x192, "IDENTIFICATION" },
{ 0x193, "Monsieur est en parfaite sante." },
{ 0x194, "Y\n" },
{ 0x193, "AU BOULOT !!!\n" }
};*/
/*
const uint8_t _font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00,
0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x7E, 0x24, 0x24, 0x7E, 0x24, 0x00,
0x08, 0x3E, 0x48, 0x3C, 0x12, 0x7C, 0x10, 0x00, 0x42, 0xA4, 0x48, 0x10, 0x24, 0x4A, 0x84, 0x00,
0x60, 0x90, 0x90, 0x70, 0x8A, 0x84, 0x7A, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x08, 0x10, 0x10, 0x10, 0x08, 0x06, 0x00, 0xC0, 0x20, 0x10, 0x10, 0x10, 0x20, 0xC0, 0x00,
0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
0x78, 0x84, 0x8C, 0x94, 0xA4, 0xC4, 0x78, 0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x7C, 0x00,
0x78, 0x84, 0x04, 0x08, 0x30, 0x40, 0xFC, 0x00, 0x78, 0x84, 0x04, 0x38, 0x04, 0x84, 0x78, 0x00,
0x08, 0x18, 0x28, 0x48, 0xFC, 0x08, 0x08, 0x00, 0xFC, 0x80, 0xF8, 0x04, 0x04, 0x84, 0x78, 0x00,
0x38, 0x40, 0x80, 0xF8, 0x84, 0x84, 0x78, 0x00, 0xFC, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00,
0x78, 0x84, 0x84, 0x78, 0x84, 0x84, 0x78, 0x00, 0x78, 0x84, 0x84, 0x7C, 0x04, 0x08, 0x70, 0x00,
0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x10, 0x10, 0x60,
0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x7C, 0x82, 0x02, 0x0C, 0x10, 0x00, 0x10, 0x00,
0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x78, 0x84, 0x84, 0xFC, 0x84, 0x84, 0x84, 0x00,
0xF8, 0x84, 0x84, 0xF8, 0x84, 0x84, 0xF8, 0x00, 0x78, 0x84, 0x80, 0x80, 0x80, 0x84, 0x78, 0x00,
0xF8, 0x84, 0x84, 0x84, 0x84, 0x84, 0xF8, 0x00, 0x7C, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7C, 0x00,
0xFC, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x7C, 0x80, 0x80, 0x8C, 0x84, 0x84, 0x7C, 0x00,
0x84, 0x84, 0x84, 0xFC, 0x84, 0x84, 0x84, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00,
0x04, 0x04, 0x04, 0x04, 0x84, 0x84, 0x78, 0x00, 0x8C, 0x90, 0xA0, 0xE0, 0x90, 0x88, 0x84, 0x00,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFC, 0x00, 0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00,
0x84, 0xC4, 0xA4, 0x94, 0x8C, 0x84, 0x84, 0x00, 0x78, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00,
0xF8, 0x84, 0x84, 0xF8, 0x80, 0x80, 0x80, 0x00, 0x78, 0x84, 0x84, 0x84, 0x84, 0x8C, 0x7C, 0x03,
0xF8, 0x84, 0x84, 0xF8, 0x90, 0x88, 0x84, 0x00, 0x78, 0x84, 0x80, 0x78, 0x04, 0x84, 0x78, 0x00,
0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00,
0x84, 0x84, 0x84, 0x84, 0x84, 0x48, 0x30, 0x00, 0x82, 0x82, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x00,
0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x00, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00,
0xFC, 0x04, 0x08, 0x10, 0x20, 0x40, 0xFC, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x04, 0x3C, 0x44, 0x3C, 0x00,
0x40, 0x40, 0x78, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x40, 0x40, 0x40, 0x3C, 0x00,
0x04, 0x04, 0x3C, 0x44, 0x44, 0x44, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x44, 0x7C, 0x40, 0x3C, 0x00,
0x38, 0x44, 0x40, 0x60, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3C, 0x44, 0x44, 0x3C, 0x04, 0x78,
0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x42, 0x3C, 0x40, 0x40, 0x46, 0x48, 0x70, 0x48, 0x46, 0x00,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00,
0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0x00, 0x00, 0x78, 0x44, 0x44, 0x78, 0x40, 0x40, 0x00, 0x00, 0x3C, 0x44, 0x44, 0x3C, 0x04, 0x04,
0x00, 0x00, 0x4C, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3C, 0x40, 0x38, 0x04, 0x78, 0x00,
0x10, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00,
0x00, 0x00, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x00,
0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x42, 0x22, 0x24, 0x18, 0x08, 0x30,
0x00, 0x00, 0x7C, 0x08, 0x10, 0x20, 0x7C, 0x00, 0x60, 0x90, 0x20, 0x40, 0xF0, 0x00, 0x00, 0x00,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x38, 0x44, 0xBA, 0xA2, 0xBA, 0x44, 0x38, 0x00,
0x38, 0x44, 0x82, 0x82, 0x44, 0x28, 0xEE, 0x00, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA
};*/
}