diff --git a/.gitignore b/.gitignore index 957ff01..f8adb17 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ !.vscode/*.code-snippets # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode +build +html \ No newline at end of file diff --git a/Makefile b/Makefile index 17e527d..91d392a 100644 --- a/Makefile +++ b/Makefile @@ -104,13 +104,20 @@ export OUTPUT := $(CURDIR)/$(TARGET) .PHONY: all clean #--------------------------------------------------------------------------------- -all: $(BUILD) generated_lut.cpp +all: $(BUILD) /usr/local/bin/http-server @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile # Don't know what I'm doing here generated_lut.cpp: /home/heath/ti-mario-kart-py/compress.py lookup_gen_config.yaml /usr/bin/env /bin/python3.10 /home/heath/ti-mario-kart-py/compress.py > generated_lut.cpp +# Still not really sure what I'm doing here +html/index.html: generated_lut.cpp + emcc -D FXCG_MOCK -Ifxcg-mock/include -g src/main.c ./fxcg-mock/include/fxcg/*.c -o html/index.html + +browser: html/index.html + emrun --browser=chromium --browser_args=--auto-open-devtools-for-tabs html/index.html + $(BUILD): @mkdir $@ diff --git a/build/main.o b/build/main.o index 396dc9f..ba4f316 100644 Binary files a/build/main.o and b/build/main.o differ diff --git a/fxcg-mock/include/fxcg/display.c b/fxcg-mock/include/fxcg/display.c new file mode 100644 index 0000000..0f35c87 --- /dev/null +++ b/fxcg-mock/include/fxcg/display.c @@ -0,0 +1,66 @@ +#include +#include + +unsigned short screen[384 * 216]; + +#define false 0 +#define true 0 + +#define byte unsigned char + +void Copy_ToCanvas(uint32_t* ptr, int w, int h) { + EM_ASM_({ + let data = Module.HEAPU8.slice($0, $0 + $1 * $2 * 4); + let context = Module['canvas'].getContext('2d'); + let imageData = context.getImageData(0, 0, $1, $2); + imageData.data.set(data); + context.putImageData(imageData, 0, 0); + }, ptr, w, h); +} + +/* static void main_loop() +{ + // memset(screen, 0, 320*320*4); // Clear screen + int screen[320*320],idx=0; + for (int x=0; x<320*320; x++) + screen[idx++] = 0xff000000; + for (int x=0; x<320; x++) + for (int y=0; y<320; y++) + screen[320*(x|y) + (x&y)]= 0xffffffff; // set pixel(x or y, x and y) to white... (will draw a serpinsky triangle) + Copy_ToCanvas(screen, 320, 320); +} */ + +void* GetVRAMAddress(void) { + emscripten_set_canvas_size(384, 216); + return &screen; +} + +void PrintXY(int x, int y, const char *string, int mode, int color) { + printf("%s\n", string + 2); +} + +void Bdisp_EnableColor(int n) {} + +void Bdisp_PutDisp_DD(void) { + unsigned int screencopy[384 * 216]; + for (int i = 0; i < (384 * 216); i++) { + int c = screen[i]; + // https://gist.github.com/companje/11deb82e807f2cf927b3a0da1646e795#file-rgb565-pde-L8 + byte r = (byte)(((c & 0xF800) >> 11) << 3); + byte g = (byte)(((c & 0x7E0) >> 5) << 2); + byte b = (byte)(((c & 0x1F)) << 3); + unsigned int argb = 0xff000000 | ((int)b << 16) | ((int)g << 8) | (int)r; + screencopy[i] = argb; + } + Copy_ToCanvas(screencopy, 384, 216); +} + +void Bdisp_PutDisp_DD_stripe(int y1, int y2) { + Bdisp_PutDisp_DD(); +} + +void Bdisp_AllClr_VRAM(void) { + for (int i = 0; i < (384 * 216); i++) { + screen[i] = 0xffffffff; + } +} diff --git a/fxcg-mock/include/fxcg/display.h b/fxcg-mock/include/fxcg/display.h new file mode 100644 index 0000000..b81d593 --- /dev/null +++ b/fxcg-mock/include/fxcg/display.h @@ -0,0 +1,376 @@ +#ifndef __FXCG_DISPLAY_H +#define __FXCG_DISPLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define LCD_WIDTH_PX 384 +#define LCD_HEIGHT_PX 216 + +typedef unsigned short color_t; + +//General display manipulating syscalls: +struct display_fill { + int x1; + int y1; + int x2; + int y2; + unsigned char mode; +}; +void Bdisp_AreaClr( struct display_fill *area, unsigned char P2, unsigned short color ); +void Bdisp_EnableColor( int n ); +//Frame control: +void DrawFrame( int color ); +unsigned short FrameColor( int mode, unsigned short color ); +void DrawFrameWorkbench( int, int, int, int, int ); +//VRAM general display manipulating syscalls: +void* GetVRAMAddress(void); // Return a pointer to the system's video memory. +void* GetSecondaryVRAMAddress(void); // Return a pointer the system's secondary video memory. +void Bdisp_AllClr_VRAM( void ); +void Bdisp_SetPoint_VRAM( int x, int y, int color ); +void Bdisp_SetPointWB_VRAM( int x, int y, int color ); +unsigned short Bdisp_GetPoint_VRAM( int x, int y ); +void SaveVRAM_1( void ); +void LoadVRAM_1( void ); +void Bdisp_Fill_VRAM( int color, int mode ); +//DD display manipulating syscalls: +void Bdisp_AreaClr_DD_x3( void*p1 ); +void Bdisp_DDRegisterSelect( int registerno ); +void Bdisp_PutDisp_DD( void ); +void Bdisp_PutDisp_DD_stripe( int y1, int y2 ); +void Bdisp_SetPoint_DD( int x, int y, int color ); +unsigned short Bdisp_GetPoint_DD_Workbench( int x, int y ); +unsigned short Bdisp_GetPoint_DD( int x, int y ); +void DirectDrawRectangle( int x1, int y1, int x2, int y2, unsigned short color ); +void HourGlass( void ); +void Bdisp_DefineDMARange(int x1, int x2, int y1, int y2); +unsigned short Bdisp_WriteDDRegister3_bit7(int value); + +// Graphic writing: +struct display_graph { + int x; + int y; + int xofs; + int yofs; + int width; + int height; + char colormode; + char zero4; + char P20_1; + char P20_2; + int bitmap; + char color_idx1; + char color_idx2; + char color_idx3; + char P20_3; + char writemodify; + char writekind; + char zero6; + char one1; + int transparency; +}; + +void Bdisp_WriteGraphVRAM(struct display_graph* gd); +void Bdisp_WriteGraphDD_WB(struct display_graph* gd); + +//Shape drawing: +struct display_shape { + int dx; + int dy; + int wx; + int wy; + int color; + struct display_fill saved; +}; +void Bdisp_ShapeBase3XVRAM( void*shape ); +void Bdisp_ShapeBase( unsigned char*work, struct display_shape *shape, int color, int line_width, int zero1, int zero2 ); +void Bdisp_ShapeToVRAM16C( void*, int color ); +void Bdisp_ShapeToDD( void*shape, int color ); +//Background-related syscalls +void SetBackGround( int ); +void WriteBackground( void*target, int width, int height, void*source, int, int, int ); + +//Message boxes, error messages, dialogs and the like: +void Box( int, int, int, int, int ); +void BoxInnerClear( int ); +void Box2( int, int ); +void BoxYLimits( int lines, int*top, int*bottom ); +void AUX_DisplayErrorMessage( int msgno ); +void MsgBoxPush( int lines ); +void MsgBoxPop( void ); +void DisplayMessageBox( unsigned char*message ); +short CharacterSelectDialog( void ); +unsigned char ColorIndexDialog1( unsigned char initial_index, unsigned short disable_mask ); +void MsgBoxMoveWB( void*buffer, int x0, int y0, int x1, int y1, int direction ); //it's more general purpose, works not only for MsgBoxes but for any VRAM contents. + +//Cursor manipulating syscalls: +void locate_OS( int X, int y ); +void Cursor_SetFlashOn( unsigned char cursor_type ); +void Cursor_SetFlashOff( void ); +int SetCursorFlashToggle( int ); +void Keyboard_CursorFlash( void ); + +//Character printing syscalls: +enum +{ + TEXT_COLOR_BLACK = 0, + TEXT_COLOR_BLUE = 1, + TEXT_COLOR_GREEN = 2, + TEXT_COLOR_CYAN = 3, + TEXT_COLOR_RED = 4, + TEXT_COLOR_PURPLE = 5, + TEXT_COLOR_YELLOW = 6, + TEXT_COLOR_WHITE = 7 +}; + +enum +{ + TEXT_MODE_NORMAL = 0x00, + TEXT_MODE_INVERT = 0x01, + TEXT_MODE_TRANSPARENT_BACKGROUND = 0x20, + TEXT_MODE_AND = 0x21 +}; +void PrintLine(const char *msg, int imax); +void PrintLine2(int, int, const char *, int, int, int, int, int); +void PrintXY_2( int mode, int x, int y, int msgno, int color ); +void PrintXY( int x, int y, const char *string, int mode, int color ); +void PrintCXY( int, int, const char *, int, int, int, int, int, int ); +void PrintGlyph( int, int, unsigned char*glyph, int, int color, int back_color, int ); +void*GetMiniGlyphPtr( unsigned short mb_glyph_no, unsigned short*glyph_info ); +void PrintMiniGlyph(int x, int y, void*glyph, int mode_flags, int glyph_width, int, int, int, int, int color, int back_color, int ); +void PrintMini( int *x, int *y, const char *MB_string, int mode_flags, unsigned int xlimit, int P6, int P7, int color, int back_color, int writeflag, int P11 ); +void PrintMiniMini( int *x, int *y, const char *MB_string, int mode1, char color, int mode2 ); +void Print_OS( const char*msg, int mode, int zero2 ); +void Bdisp_WriteSystemMessage( int x, int y, int msgno, int mode, char color3 ); + +//Progressbars and scrollbars: +struct scrollbar +{ + unsigned int I1; // unknown changes indicator height, set to 0 + unsigned int indicatormaximum; // max logical indicator range + unsigned int indicatorheight; // height of the indicator in units + unsigned int indicatorpos; // indicator position in units of max + unsigned int I5; // unknown, set to 0 + unsigned short barleft; // x position of bar + unsigned short bartop; // y position of bar + unsigned short barheight; // height of bar + unsigned short barwidth; // width of bar +} ; +void Scrollbar(struct scrollbar *scrollbar); +void StandardScrollbar( void* ); +void ProgressBar(int, int ); +void ProgressBar0(int P1, int P2, int P3, int current, int max); +void ProgressBar2(unsigned char *heading, int current, int max); + +//Status area/header related syscalls: +// define status area +#define DSA_CLEAR 0 +#define DSA_SETDEFAULT 1 +// status area flags +#define SAF_BATTERY 0x0001 +#define SAF_ALPHA_SHIFT 0x0002 +#define SAF_SETUP_INPUT_OUTPUT 0x0004 +#define SAF_SETUP_FRAC_RESULT 0x0008 +#define SAF_SETUP_ANGLE 0x0010 +#define SAF_SETUP_COMPLEX_MODE 0x0020 +#define SAF_SETUP_DISPLAY 0x0040 +#define SAF_TEXT 0x0100 +#define SAF_GLYPH 0x0200 +int DefineStatusAreaFlags( int, int, void*, void* ); +void DefineStatusGlyph( int, void* ); +void DefineStatusMessage( char*msg, short P2, char P3, char P4 ); +void DisplayStatusArea( void ); +void DrawHeaderLine( void ); +void EnableStatusArea( int ); +void Bdisp_HeaderFill( unsigned char color_idx1, unsigned char color_idx2 ); +void Bdisp_HeaderFill2( unsigned int, unsigned int, unsigned char, unsigned char ); +void Bdisp_HeaderText( void ); +void Bdisp_HeaderText2( void ); +void EnableDisplayHeader( int, int ); +//Status area icon syscalls: (it may be more appropriate to use the status area flags) +void APP_EACT_StatusIcon( int ); //not sure what this is exactly for, if it displays something on screen it's here, otherwise in app.h. will test some day (gbl08ma) +void SetupMode_StatusIcon( void ); //not sure what this does, doesn't seem to be documented anywhere. will test some day (gbl08ma) +void d_c_Icon( unsigned int ); +void BatteryIcon( unsigned int ); +void KeyboardIcon( unsigned int ); +void LineIcon( unsigned int ); +void NormIcon( unsigned int ); +void RadIcon( unsigned int ); +void RealIcon( unsigned int ); + +//Other: +void FKey_Display( int, void* ); +void GetFKeyPtr( int, void* ); +void DispInt( int, int ); //not sure what this does, doesn't seem to be documented anywhere. will test some day (gbl08ma) +int LocalizeMessage1( int msgno, char*result ); +int SMEM_MapIconToExt( unsigned char*filename, unsigned short*foldername, unsigned int*msgno, unsigned short*iconbuffer ); // despite starting with SMEM, this is mostly a graphical function used to get icons for different file types. + +//Not syscalls (defined within libfxcg): +void VRAM_CopySprite(const color_t* data, int x, int y, int width, int height); +void VRAM_XORSprite(const color_t* data, int x, int y, int width, int height); + +// Original Author, Shaun McFall (Merthsoft) +// Used with permission + +#define COLOR_ALICEBLUE (color_t)0xF7DF +#define COLOR_ANTIQUEWHITE (color_t)0xFF5A +#define COLOR_AQUA (color_t)0x07FF +#define COLOR_AQUAMARINE (color_t)0x7FFA +#define COLOR_AZURE (color_t)0xF7FF +#define COLOR_BEIGE (color_t)0xF7BB +#define COLOR_BISQUE (color_t)0xFF38 +#define COLOR_BLACK (color_t)0x0000 +#define COLOR_BLANCHEDALMOND (color_t)0xFF59 +#define COLOR_BLUE (color_t)0x001F +#define COLOR_BLUEVIOLET (color_t)0x895C +#define COLOR_BROWN (color_t)0xA145 +#define COLOR_BURLYWOOD (color_t)0xDDD0 +#define COLOR_CADETBLUE (color_t)0x5CF4 +#define COLOR_CHARTREUSE (color_t)0x7FE0 +#define COLOR_CHOCOLATE (color_t)0xD343 +#define COLOR_CORAL (color_t)0xFBEA +#define COLOR_CORNFLOWERBLUE (color_t)0x64BD +#define COLOR_CORNSILK (color_t)0xFFDB +#define COLOR_CRIMSON (color_t)0xD8A7 +#define COLOR_CYAN (color_t)0x07FF +#define COLOR_DARKBLUE (color_t)0x0011 +#define COLOR_DARKCYAN (color_t)0x0451 +#define COLOR_DARKGOLDENROD (color_t)0xBC21 +#define COLOR_DARKGRAY (color_t)0xAD55 +#define COLOR_DARKGREEN (color_t)0x0320 +#define COLOR_DARKKHAKI (color_t)0xBDAD +#define COLOR_DARKMAGENTA (color_t)0x8811 +#define COLOR_DARKOLIVEGREEN (color_t)0x5345 +#define COLOR_DARKORANGE (color_t)0xFC60 +#define COLOR_DARKORCHID (color_t)0x9999 +#define COLOR_DARKRED (color_t)0x8800 +#define COLOR_DARKSALMON (color_t)0xECAF +#define COLOR_DARKSEAGREEN (color_t)0x8DF1 +#define COLOR_DARKSLATEBLUE (color_t)0x49F1 +#define COLOR_DARKSLATEGRAY (color_t)0x2A69 +#define COLOR_DARKTURQUOISE (color_t)0x067A +#define COLOR_DARKVIOLET (color_t)0x901A +#define COLOR_DEEPPINK (color_t)0xF8B2 +#define COLOR_DEEPSKYBLUE (color_t)0x05FF +#define COLOR_DIMGRAY (color_t)0x6B4D +#define COLOR_DODGERBLUE (color_t)0x1C9F +#define COLOR_FIREBRICK (color_t)0xB104 +#define COLOR_FLORALWHITE (color_t)0xFFDE +#define COLOR_FORESTGREEN (color_t)0x2444 +#define COLOR_FUCHSIA (color_t)0xF81F +#define COLOR_GAINSBORO (color_t)0xDEFB +#define COLOR_GHOSTWHITE (color_t)0xFFDF +#define COLOR_GOLD (color_t)0xFEA0 +#define COLOR_GOLDENROD (color_t)0xDD24 +#define COLOR_GRAY (color_t)0x8410 +#define COLOR_GREEN (color_t)0x0400 +#define COLOR_GREENYELLOW (color_t)0xAFE5 +#define COLOR_HONEYDEW (color_t)0xF7FE +#define COLOR_HOTPINK (color_t)0xFB56 +#define COLOR_INDIANRED (color_t)0xCAEB +#define COLOR_INDIGO (color_t)0x4810 +#define COLOR_IVORY (color_t)0xFFFE +#define COLOR_KHAKI (color_t)0xF731 +#define COLOR_LAVENDER (color_t)0xE73F +#define COLOR_LAVENDERBLUSH (color_t)0xFF9E +#define COLOR_LAWNGREEN (color_t)0x7FE0 +#define COLOR_LEMONCHIFFON (color_t)0xFFD9 +#define COLOR_LIGHTBLUE (color_t)0xAEDC +#define COLOR_LIGHTCORAL (color_t)0xF410 +#define COLOR_LIGHTCYAN (color_t)0xE7FF +#define COLOR_LIGHTGOLDENRODYELLOW (color_t)0xFFDA +#define COLOR_LIGHTGRAY (color_t)0xD69A +#define COLOR_LIGHTGREEN (color_t)0x9772 +#define COLOR_LIGHTPINK (color_t)0xFDB8 +#define COLOR_LIGHTSALMON (color_t)0xFD0F +#define COLOR_LIGHTSEAGREEN (color_t)0x2595 +#define COLOR_LIGHTSKYBLUE (color_t)0x867F +#define COLOR_LIGHTSLATEGRAY (color_t)0x7453 +#define COLOR_LIGHTSTEELBLUE (color_t)0xB63B +#define COLOR_LIGHTYELLOW (color_t)0xFFFC +#define COLOR_LIME (color_t)0x07E0 +#define COLOR_LIMEGREEN (color_t)0x3666 +#define COLOR_LINEN (color_t)0xFF9C +#define COLOR_MAGENTA (color_t)0xF81F +#define COLOR_MAROON (color_t)0x8000 +#define COLOR_MEDIUMAQUAMARINE (color_t)0x6675 +#define COLOR_MEDIUMBLUE (color_t)0x0019 +#define COLOR_MEDIUMORCHID (color_t)0xBABA +#define COLOR_MEDIUMPURPLE (color_t)0x939B +#define COLOR_MEDIUMSEAGREEN (color_t)0x3D8E +#define COLOR_MEDIUMSLATEBLUE (color_t)0x7B5D +#define COLOR_MEDIUMSPRINGGREEN (color_t)0x07D3 +#define COLOR_MEDIUMTURQUOISE (color_t)0x4E99 +#define COLOR_MEDIUMVIOLETRED (color_t)0xC0B0 +#define COLOR_MIDNIGHTBLUE (color_t)0x18CE +#define COLOR_MINTCREAM (color_t)0xF7FF +#define COLOR_MISTYROSE (color_t)0xFF3C +#define COLOR_MOCCASIN (color_t)0xFF36 +#define COLOR_NAVAJOWHITE (color_t)0xFEF5 +#define COLOR_NAVY (color_t)0x0010 +#define COLOR_OLDLACE (color_t)0xFFBC +#define COLOR_OLIVE (color_t)0x8400 +#define COLOR_OLIVEDRAB (color_t)0x6C64 +#define COLOR_ORANGE (color_t)0xFD20 +#define COLOR_ORANGERED (color_t)0xFA20 +#define COLOR_ORCHID (color_t)0xDB9A +#define COLOR_PALEGOLDENROD (color_t)0xEF55 +#define COLOR_PALEGREEN (color_t)0x9FD3 +#define COLOR_PALETURQUOISE (color_t)0xAF7D +#define COLOR_PALEVIOLETRED (color_t)0xDB92 +#define COLOR_PAPAYAWHIP (color_t)0xFF7A +#define COLOR_PEACHPUFF (color_t)0xFED7 +#define COLOR_PERU (color_t)0xCC27 +#define COLOR_PINK (color_t)0xFE19 +#define COLOR_PLUM (color_t)0xDD1B +#define COLOR_POWDERBLUE (color_t)0xB71C +#define COLOR_PURPLE (color_t)0x8010 +#define COLOR_RED (color_t)0xF800 +#define COLOR_ROSYBROWN (color_t)0xBC71 +#define COLOR_ROYALBLUE (color_t)0x435C +#define COLOR_SADDLEBROWN (color_t)0x8A22 +#define COLOR_SALMON (color_t)0xFC0E +#define COLOR_SANDYBROWN (color_t)0xF52C +#define COLOR_SEAGREEN (color_t)0x2C4A +#define COLOR_SEASHELL (color_t)0xFFBD +#define COLOR_SIENNA (color_t)0xA285 +#define COLOR_SILVER (color_t)0xC618 +#define COLOR_SKYBLUE (color_t)0x867D +#define COLOR_SLATEBLUE (color_t)0x6AD9 +#define COLOR_SLATEGRAY (color_t)0x7412 +#define COLOR_SNOW (color_t)0xFFDF +#define COLOR_SPRINGGREEN (color_t)0x07EF +#define COLOR_STEELBLUE (color_t)0x4416 +#define COLOR_TAN (color_t)0xD5B1 +#define COLOR_TEAL (color_t)0x0410 +#define COLOR_THISTLE (color_t)0xDDFB +#define COLOR_TOMATO (color_t)0xFB08 +#define COLOR_TURQUOISE (color_t)0x471A +#define COLOR_VIOLET (color_t)0xEC1D +#define COLOR_WHEAT (color_t)0xF6F6 +#define COLOR_WHITE (color_t)0xFFFF +#define COLOR_WHITESMOKE (color_t)0xF7BE +#define COLOR_YELLOW (color_t)0xFFE0 +#define COLOR_YELLOWGREEN (color_t)0x9E66 + +// TW : So far this appears to be the most reliable way to determine model +typedef enum { + DT_CG20, // or CG10 + DT_CG50, + DT_Winsim +} DeviceType; + +inline DeviceType getDeviceType() { +#if TARGET_PRIZM + return (unsigned int)GetVRAMAddress() == 0xAC000000 ? DT_CG50 : DT_CG20; +#else + return DT_Winsim; +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif /* __FXCG_DISPLAY_H */ diff --git a/fxcg-mock/include/fxcg/keyboard.c b/fxcg-mock/include/fxcg/keyboard.c new file mode 100644 index 0000000..e6feeb0 --- /dev/null +++ b/fxcg-mock/include/fxcg/keyboard.c @@ -0,0 +1,44 @@ +#include +#include +#include + +// Listen to EMSCRIPTEN_EVENT_KEYDOWN and EMSCRIPTEN_EVENT_KEYUP +// and print the key code to the console. + +unsigned char keysPressed[256] = {0}; + +int setKeyState(unsigned char key, unsigned char state) { + switch (key) { + case 37: // left arrow + keysPressed[38] = state; + break; + case 39: // right arrow + keysPressed[27] = state; + break; + case 88: // x + keysPressed[78] = state; + break; + } + return 0; +} + +int keyDownEvent(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) { + printf("keyDownEvent: %d\n", keyEvent->keyCode); + setKeyState(keyEvent->keyCode, 1); + return 0; +} + +int keyUpEvent(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) { + printf("keyUpEvent: %d\n", keyEvent->keyCode); + setKeyState(keyEvent->keyCode, 0); + return 0; +} + +int keydown(int basic_keycode) { + return keysPressed[basic_keycode]; +} + +void setupKeyboard() { + emscripten_set_keydown_callback("html", 0, 0, keyDownEvent); + emscripten_set_keyup_callback("html", 0, 0, keyUpEvent); +} diff --git a/fxcg-mock/include/fxcg/keyboard.h b/fxcg-mock/include/fxcg/keyboard.h new file mode 100644 index 0000000..1d81497 --- /dev/null +++ b/fxcg-mock/include/fxcg/keyboard.h @@ -0,0 +1,235 @@ +#ifndef __KEYBOARD_H__ +#define __KEYBOARD_H__ + +// Character codes +#define KEY_CHAR_0 0x30 +#define KEY_CHAR_1 0x31 +#define KEY_CHAR_2 0x32 +#define KEY_CHAR_3 0x33 +#define KEY_CHAR_4 0x34 +#define KEY_CHAR_5 0x35 +#define KEY_CHAR_6 0x36 +#define KEY_CHAR_7 0x37 +#define KEY_CHAR_8 0x38 +#define KEY_CHAR_9 0x39 +#define KEY_CHAR_DP 0x2e +#define KEY_CHAR_EXP 0x0f +#define KEY_CHAR_PMINUS 0x87 +#define KEY_CHAR_PLUS 0x89 +#define KEY_CHAR_MINUS 0x99 +#define KEY_CHAR_MULT 0xa9 +#define KEY_CHAR_DIV 0xb9 +#define KEY_CHAR_FRAC 0xbb +#define KEY_CHAR_LPAR 0x28 +#define KEY_CHAR_RPAR 0x29 +#define KEY_CHAR_COMMA 0x2c +#define KEY_CHAR_STORE 0x0e +#define KEY_CHAR_LOG 0x95 +#define KEY_CHAR_LN 0x85 +#define KEY_CHAR_SIN 0x81 +#define KEY_CHAR_COS 0x82 +#define KEY_CHAR_TAN 0x83 +#define KEY_CHAR_SQUARE 0x8b +#define KEY_CHAR_POW 0xa8 +#define KEY_CHAR_IMGNRY 0x7f50 +#define KEY_CHAR_LIST 0x7f51 +#define KEY_CHAR_MAT 0x7f40 +#define KEY_CHAR_EQUAL 0x3d +#define KEY_CHAR_PI 0xd0 +#define KEY_CHAR_ANS 0xc0 +#define KEY_CHAR_LBRCKT 0x5b +#define KEY_CHAR_RBRCKT 0x5d +#define KEY_CHAR_LBRACE 0x7b +#define KEY_CHAR_RBRACE 0x7d +#define KEY_CHAR_CR 0x0d +#define KEY_CHAR_CUBEROOT 0x96 +#define KEY_CHAR_RECIP 0x9b +#define KEY_CHAR_ANGLE 0x7f54 +#define KEY_CHAR_EXPN10 0xb5 +#define KEY_CHAR_EXPN 0xa5 +#define KEY_CHAR_ASIN 0x91 +#define KEY_CHAR_ACOS 0x92 +#define KEY_CHAR_ATAN 0x93 +#define KEY_CHAR_ROOT 0x86 +#define KEY_CHAR_POWROOT 0xb8 +#define KEY_CHAR_SPACE 0x20 +#define KEY_CHAR_DQUATE 0x22 +#define KEY_CHAR_VALR 0xcd +#define KEY_CHAR_THETA 0xce +#define KEY_CHAR_A 0x41 +#define KEY_CHAR_B 0x42 +#define KEY_CHAR_C 0x43 +#define KEY_CHAR_D 0x44 +#define KEY_CHAR_E 0x45 +#define KEY_CHAR_F 0x46 +#define KEY_CHAR_G 0x47 +#define KEY_CHAR_H 0x48 +#define KEY_CHAR_I 0x49 +#define KEY_CHAR_J 0x4a +#define KEY_CHAR_K 0x4b +#define KEY_CHAR_L 0x4c +#define KEY_CHAR_M 0x4d +#define KEY_CHAR_N 0x4e +#define KEY_CHAR_O 0x4f +#define KEY_CHAR_P 0x50 +#define KEY_CHAR_Q 0x51 +#define KEY_CHAR_R 0x52 +#define KEY_CHAR_S 0x53 +#define KEY_CHAR_T 0x54 +#define KEY_CHAR_U 0x55 +#define KEY_CHAR_V 0x56 +#define KEY_CHAR_W 0x57 +#define KEY_CHAR_X 0x58 +#define KEY_CHAR_Y 0x59 +#define KEY_CHAR_Z 0x5a +/* non-capital char keys, possible in the emulator when writing with the computer keyboard + and eventually in some text-entry modes. Note that one only needs to add 0x20 to the + uppercase char key codes to get the codes for the lowercase keys. +*/ +#define KEY_CHAR_LOWER_A 0x61 +#define KEY_CHAR_LOWER_B 0x62 +#define KEY_CHAR_LOWER_C 0x63 +#define KEY_CHAR_LOWER_D 0x64 +#define KEY_CHAR_LOWER_E 0x65 +#define KEY_CHAR_LOWER_F 0x66 +#define KEY_CHAR_LOWER_G 0x67 +#define KEY_CHAR_LOWER_H 0x68 +#define KEY_CHAR_LOWER_I 0x69 +#define KEY_CHAR_LOWER_J 0x6A +#define KEY_CHAR_LOWER_K 0x6B +#define KEY_CHAR_LOWER_L 0x6C +#define KEY_CHAR_LOWER_M 0x6D +#define KEY_CHAR_LOWER_N 0x6E +#define KEY_CHAR_LOWER_O 0x6F +#define KEY_CHAR_LOWER_P 0x70 +#define KEY_CHAR_LOWER_Q 0x71 +#define KEY_CHAR_LOWER_R 0x72 +#define KEY_CHAR_LOWER_S 0x73 +#define KEY_CHAR_LOWER_T 0x74 +#define KEY_CHAR_LOWER_U 0x75 +#define KEY_CHAR_LOWER_V 0x76 +#define KEY_CHAR_LOWER_W 0x77 +#define KEY_CHAR_LOWER_X 0x78 +#define KEY_CHAR_LOWER_Y 0x79 +#define KEY_CHAR_LOWER_Z 0x7A + +// Control codes +#define KEY_CTRL_NOP 0 +#define KEY_CTRL_EXE 30004 +#define KEY_CTRL_DEL 30025 +#define KEY_CTRL_AC 30015 +#define KEY_CTRL_FD 30046 +#define KEY_CTRL_UNDO 30045 +#define KEY_CTRL_XTT 30001 +#define KEY_CTRL_EXIT 30002 +#define KEY_CTRL_SHIFT 30006 +#define KEY_CTRL_ALPHA 30007 +#define KEY_CTRL_OPTN 30008 +#define KEY_CTRL_VARS 30016 +#define KEY_CTRL_UP 30018 +#define KEY_CTRL_DOWN 30023 +#define KEY_CTRL_LEFT 30020 +#define KEY_CTRL_RIGHT 30021 +#define KEY_CTRL_F1 30009 +#define KEY_CTRL_F2 30010 +#define KEY_CTRL_F3 30011 +#define KEY_CTRL_F4 30012 +#define KEY_CTRL_F5 30013 +#define KEY_CTRL_F6 30014 +#define KEY_CTRL_CATALOG 30100 +#define KEY_CTRL_FORMAT 30101 +#define KEY_CTRL_CAPTURE 30055 +#define KEY_CTRL_CLIP 30050 +#define KEY_CTRL_PASTE 30036 +#define KEY_CTRL_INS 30033 +#define KEY_CTRL_MIXEDFRAC 30054 +#define KEY_CTRL_FRACCNVRT 30026 +#define KEY_CTRL_QUIT 30029 +#define KEY_CTRL_PRGM 30028 +#define KEY_CTRL_SETUP 30037 +#define KEY_CTRL_PAGEUP 30052 +#define KEY_CTRL_PAGEDOWN 30053 +#define KEY_CTRL_MENU 30003 +#define KEY_SHIFT_OPTN 30059 +#define KEY_CTRL_RESERVE1 30060 +#define KEY_CTRL_RESERVE2 30061 +#define KEY_SHIFT_LEFT 30062 +#define KEY_SHIFT_RIGHT 30063 + +#define KEY_PRGM_ACON 10 +#define KEY_PRGM_DOWN 37 +#define KEY_PRGM_EXIT 47 +#define KEY_PRGM_F1 79 +#define KEY_PRGM_F2 69 +#define KEY_PRGM_F3 59 +#define KEY_PRGM_F4 49 +#define KEY_PRGM_F5 39 +#define KEY_PRGM_F6 29 +#define KEY_PRGM_LEFT 38 +#define KEY_PRGM_NONE 0 +#define KEY_PRGM_RETURN 31 +#define KEY_PRGM_RIGHT 27 +#define KEY_PRGM_UP 28 +#define KEY_PRGM_0 71 +#define KEY_PRGM_1 72 +#define KEY_PRGM_2 62 +#define KEY_PRGM_3 52 +#define KEY_PRGM_4 73 +#define KEY_PRGM_5 63 +#define KEY_PRGM_6 53 +#define KEY_PRGM_7 74 +#define KEY_PRGM_8 64 +#define KEY_PRGM_9 54 +#define KEY_PRGM_A 76 +#define KEY_PRGM_F 26 +#define KEY_PRGM_ALPHA 77 +#define KEY_PRGM_SHIFT 78 +#define KEY_PRGM_OPTN 68 +#define KEY_PRGM_MENU 48 + +// in Bkey_GetKeyWait function +#define KEYWAIT_HALTON_TIMEROFF 0 +#define KEYWAIT_HALTOFF_TIMEROFF 1 +#define KEYWAIT_HALTON_TIMERON 2 + +#define KEYREP_NOEVENT 0 +#define KEYREP_KEYEVENT 1 +#define KEYREP_TIMEREVENT 2 + +#ifdef __cplusplus +extern "C" { +#endif + +void Set_FKeys2( unsigned int p1 ); +void Set_FKeys1( unsigned int p1, unsigned int*P2 ); +void PRGM_GetKey_OS( unsigned char*p ); +int GetKey(int*key); +int GetKeyWait_OS(int*column, int*row, int type_of_waiting, int timeout_period, int menu, unsigned short*keycode ); +int PRGM_GetKey(); +void DisplayMBString(unsigned char *MB_string, int start, int xpos, int x, int y); +void DisplayMBString2( int P1, unsigned char*MB_string, int start, int xpos, int x, int y, int pos_to_clear, int P8, int P9 ); +void EditMBStringCtrl(unsigned char *MB_string, int posmax, int *start, int *xpos, int *key, int x, int y); +void EditMBStringCtrl2( unsigned char*MB_string, int xposmax, int*P3, int*xpos, int*key, int x, int y, int enable_pos_to_clear, int pos_to_clear ); +void EditMBStringCtrl3( unsigned char*, int xposmax, void*, void*, void*, int, int, int, int, int ); +void EditMBStringCtrl4( unsigned char*, int xposmax, void*, void*, void*, int, int, int, int, int, int ); +int EditMBStringChar(unsigned char *MB_string, int posmax, int xpos, int char_to_insert); +void Bkey_ClrAllFlags( void ); +void Bkey_SetFlag(short flagpattern); +int Keyboard_PutKeycode( int X, int Y, int Keycode); +int Keyboard_SpyMatrixCode(char*column, char*row); +void Bkey_SetAllFlags(short flags); +short Bkey_GetAllFlags( void ); + +// Mock functions +int keydown(int basic_keycode); +void setupKeyboard( void ); + +/* whether user can get into Main Menu with GetKey. 1=menu enabled, 0=menu locked. + * "Set" syscall doesn't exist, must be done through address trickery. */ +int GetGetkeyToMainFunctionReturnFlag( void ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fxcg-mock/include/fxcg/mock.c b/fxcg-mock/include/fxcg/mock.c new file mode 100644 index 0000000..cb5144f --- /dev/null +++ b/fxcg-mock/include/fxcg/mock.c @@ -0,0 +1,6 @@ +#include +#include "keyboard.h" + +void initMock() { + setupKeyboard(); +} \ No newline at end of file diff --git a/fxcg-mock/include/fxcg/mock.h b/fxcg-mock/include/fxcg/mock.h new file mode 100644 index 0000000..23f511e --- /dev/null +++ b/fxcg-mock/include/fxcg/mock.h @@ -0,0 +1 @@ +void initMock(void); \ No newline at end of file diff --git a/hello-world.g3a b/hello-world.g3a index 213879b..cbd038c 100644 Binary files a/hello-world.g3a and b/hello-world.g3a differ diff --git a/src/main.c b/src/main.c index d3061a1..c9fa477 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,13 @@ #include #include +#ifndef FXCG_MOCK #include #include #include +#else +#include +#include +#endif #include "../generated_lut.cpp" @@ -226,6 +231,7 @@ float cos(int angle) { #define PI 3.14159265358979323846 // https://www.cemetech.net/forum/viewtopic.php?p=173836&sid=9eabb0dbeddeeb6507c19c8a65dbe249 +#ifndef FXCG_MOCK int keydown(int basic_keycode) { const unsigned short* keyboard_register = (unsigned short*)0xA44B0000; int row, col, word, bit; @@ -235,6 +241,7 @@ int keydown(int basic_keycode) { bit = col + 8 * (row & 1); return (0 != (keyboard_register[word] & 1 << bit)); } +#endif void cameraBehind(short x, short y, short objectAngle, short distance) { // objectAngle = 90 - objectAngle; @@ -306,6 +313,7 @@ int frameCount = 0; void main_loop() { // Main game loop + #ifndef FXCG_MOCK int currentTime = RTC_GetTicks(); // If 1 second has passed, print framerate if (currentTime - lastTime >= 128) { @@ -324,6 +332,7 @@ void main_loop() { frameCount = 0; } + #endif // Grass or sand = more friction unsigned char currentTile = getTileType(kartX / scale, kartY / scale); @@ -401,6 +410,7 @@ void main_loop() { } exeWasPressed = exePressed; + #ifndef FXCG_MOCK if (keydown(KEY_PRGM_MENU)) { // Allow the OS to handle exiting to the menu int key; @@ -408,9 +418,12 @@ void main_loop() { Bdisp_EnableColor(1); fillSky(0, LCD_HEIGHT_PX); } + #endif if (keydown(KEY_PRGM_ACON)) { + #ifndef FXCG_MOCK PowerOff(1); + #endif fillSky(0, LCD_HEIGHT_PX); } @@ -439,15 +452,25 @@ void main_loop() { } int main() { + #ifdef FXCG_MOCK + initMock(); + #endif + VRAM = (color_t*)GetVRAMAddress(); Bdisp_EnableColor(1); fillSky(0, LCD_HEIGHT_PX); + #ifndef FXCG_MOCK lastTime = RTC_GetTicks(); + #endif + #ifdef FXCG_MOCK + emscripten_set_main_loop(main_loop, 30, 1); + #else while (1) { main_loop(); } + #endif /* color_t* VRAM = (color_t*)0xA8000000; // emu address of VRAM VRAM += (LCD_WIDTH_PX*y + x);