From 1c1968e3ab3bc79277359cc286b672f7759f33d9 Mon Sep 17 00:00:00 2001 From: jeffman Date: Sat, 3 Aug 2019 20:33:28 -0400 Subject: [PATCH] Preliminary string printing Had to change the signature of the base print_chr function because the file select screen uses a lot of non-standard memory layouts. For example, the tilemap has a variable width instead of the standard 32 tiles. --- notes/m2-fileselect.txt | 17 +++++++- src/c/vwf.c | 64 +++++++++++++++++++++++++---- src/c/vwf.h | 3 +- src/data/m2-fileselect-tileset.bin | Bin 0 -> 5081 bytes src/m2-hack.asm | 7 ++++ 5 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 src/data/m2-fileselect-tileset.bin diff --git a/notes/m2-fileselect.txt b/notes/m2-fileselect.txt index 5ad205b..41635c3 100644 --- a/notes/m2-fileselect.txt +++ b/notes/m2-fileselect.txt @@ -16,8 +16,23 @@ It seems to get fully overwritten, so we can replace it with all blank tiles ---- -We also need to blank out the font that gets loaded to VRAM at 6008000 +We also need to blank out the font that gets decompressed from 86D9808 to VRAM at 6008000 ---- Note that the palette on these screens uses 0x1 for background, 0x9 for foreground + +---- + +We need to allocate more space for the strings... The same only allocates 32 bytes per file slot, +but we need at least 41: + + "X: " 3 + "NAME " 5 + [FE 5F xx] 3 + "Level: XX" 9 + [FE 5F xx] 3 + "Text speed: Medium" 18 + = 41 + +~8001EAE: file slot number formatting diff --git a/src/c/vwf.c b/src/c/vwf.c index 79f90c1..4518957 100644 --- a/src/c/vwf.c +++ b/src/c/vwf.c @@ -46,6 +46,56 @@ byte reduce_bit_depth(int row, int foreground) return lower | (upper << 4); } +void print_file_string(int x, int y, int length, byte *str, int unknown) +{ + int *tilesetBasePtr = (int *)(0x82B79B4 + (unknown * 20)); + int width = tilesetBasePtr[2]; + unsigned short *tilesetDestPtr = (unsigned short *)(tilesetBasePtr[0]); + + int pixelX = x * 8; + int pixelY = y * 8; + + for (int i = 0; i < length; i++) + { + byte chr = str[i]; + + if (chr == 0xFF) + { + break; // the game does something else here, haven't looked into what exactly + } + else if (chr == 0xFE) + { + // Define 0xFE as a control code + byte cmd = str[++i]; + switch (cmd) + { + case CUSTOMCC_ADD_X: + pixelX += str[++i]; + break; + + case CUSTOMCC_SET_X: + pixelX = str[++i]; + break; + } + continue; + } + + chr = decode_character(chr); + int pixels = print_character_with_callback( + chr, + pixelX, + pixelY, + 0, + 9, + vram + 0x2000, + &get_tile_number_grid, + tilesetDestPtr, + width); + + pixelX += pixels; + } +} + byte print_character(byte chr, int x, int y) { return print_character_formatted(chr, x, y, 0, 0xF); @@ -67,12 +117,12 @@ byte print_character_formatted(byte chr, int x, int y, int font, int foreground) return 8; } - return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, TRUE); + return print_character_with_callback(chr, x, y, font, foreground, vram, &get_tile_number_with_offset, *tilemap_pointer, 32); } byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground) { - return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, FALSE); + return print_character_with_callback(chr, xOffset, 0, font, foreground, dest, &get_tile_number_grid, NULL, 32); } // Prints a special tile. Pixels are copied to the VWF buffer. @@ -110,7 +160,7 @@ void map_tile(unsigned short tile, int x, int y) } byte print_character_with_callback(byte chr, int x, int y, int font, int foreground, - int *dest, int (*getTileCallback)(int, int), int useTilemap) + int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth) { int tileWidth = m2_font_widths[font]; int tileHeight = m2_font_heights[font]; @@ -149,8 +199,8 @@ byte print_character_with_callback(byte chr, int x, int y, int font, int foregro dest[(tileIndex * 8) + row] = canvasRow; } - if (useTilemap) - (*tilemap_pointer)[tileX + dTileX + ((tileY + dTileY) * 32)] = paletteMask | tileIndex; + if (tilemapPtr != NULL) + tilemapPtr[tileX + dTileX + ((tileY + dTileY) * tilemapWidth)] = paletteMask | tileIndex; if (renderedWidth - leftPortionWidth > 0 && leftPortionWidth < 8) { @@ -171,8 +221,8 @@ byte print_character_with_callback(byte chr, int x, int y, int font, int foregro dest[(tileIndex * 8) + row] = canvasRow; } - if (useTilemap) - (*tilemap_pointer)[tileX + dTileX + 1 + ((tileY + dTileY) * 32)] = paletteMask | tileIndex; + if (tilemapPtr != NULL) + tilemapPtr[tileX + dTileX + 1 + ((tileY + dTileY) * tilemapWidth)] = paletteMask | tileIndex; } renderedWidth -= 8; diff --git a/src/c/vwf.h b/src/c/vwf.h index cfb1621..167acab 100644 --- a/src/c/vwf.h +++ b/src/c/vwf.h @@ -35,7 +35,7 @@ void print_special_character(int tile, int x, int y); void map_special_character(unsigned short tile, int x, int y); void map_tile(unsigned short tile, int x, int y); byte print_character_with_callback(byte chr, int x, int y, int font, int foreground, - int *dest, int (*getTileCallback)(int, int), int useTilemap); + int *dest, int (*getTileCallback)(int, int), unsigned short *tilemapPtr, int tilemapWidth); byte print_character_to_ram(byte chr, int *dest, int xOffset, int font, int foreground); int print_window_header_string(int *dest, byte *str, int x, int y); void clear_window_header(int *dest); @@ -65,6 +65,7 @@ void print_number_menu_current(byte digit, WINDOW* window); void clear_number_menu(WINDOW* window); void format_cash_window(int value, int padding, byte* str); void handle_first_window(WINDOW* window); +void print_file_string(int x, int y, int length, byte *str, int unknown); extern unsigned short m2_coord_table[]; extern int m2_bits_to_nybbles[]; diff --git a/src/data/m2-fileselect-tileset.bin b/src/data/m2-fileselect-tileset.bin new file mode 100644 index 0000000000000000000000000000000000000000..c8c22f5794742d4adfc738f64e506a86e6056bff GIT binary patch literal 5081 zcmeHJZ%kX)6+f4o01fSYpI@mB*7B}x22H6pQ|C`rn!FeApfp?inEMi|kzxYHnb#_^ zmn@E!bk8nz^0a=48I1I8lOUsOG*)ev`hltY6SPdLRx~ATs#RLG;*~6P$_HN{jHYb4 zyKaQCNu(d5>{IZ4dcN=7cg{V(-}!S7fi$R+#L$hwZ%nVxR$u%tBX=|(1Xackwe(V) zYUzbkLrbsE_f$EALPoh^#J~}Y0Wd`joW@!#fl}h<^HuqLp%830V7ummdfVO*`<~s6 zQuP}S`MSG7>1rEM0(Bc=seRo)0kwWa9UDud*8uOD1pF(g6c@n^-8VM&7T`C)4_MNg z(3-F$H5tJ*a@a7cVP|#c_r-eyT%D3v2E2BY6bu?f*#!7$gEUB#LU|`BM&l+4f-=-@ zB2`^@n4n-V;UMe5Pa3J?Bht(eAQ#}nlB8M|sl4I$Tk!d{W$6iohswTT{hn47JjV~a zD7FsQyDY&Vf(Bu;10)FmQ$5G_Fow@K{lP1WRUh+@l%l`RW0I@2v z?8WQed>zN2VN7IvjN9y_5ZW+ug9DZ?7&>tRu@371px)EbHN*RcQr- zeT9H1->9=%GCHdbzz$KufuS5?$^S!?tZ1Gfp^wWma*-j5!ZY$>fo&~)C`rjw3R0!o zo2-$_?W9!GpTks<6j!o;LX>g%Qb8fDmtY5V=@l-CMs+!9+Tf=RnyQ;=myQF!S9310y~6m}bFL&gT_i8P;@NvP z1s+hqpI3P6>%^mBfm>uZQ_A)UJ!!EyoE}lSCgBWf;4IoYjaMZ~x&eZyk4<8vf8ESXYFO(u&6C%x4A|U*!B<*SlheE4(xo zOlI=Hj$fJ$?=y3OUpJ9&@#OK|BO6Z>wY@c=!1`ng)=^ZpzebYi%m0GiuufOdH2k*g z9^3wiJWCL%$N}yMg_~@>2kAr5WZS-dzEWHVgQfc? z_uMS?CJ?f`KWoZ;cJyCZ5-3b@T`>=u3sHG|ftOHx3M6kXOdaD)>6vVZ@=~3yKKo#g zsKp2u<>OqQ*3pQ9FUpH>jVW~72f-=%pCNfc$E{OzlC=`oz;lVhzWAVYZSlJ$7l{1@A2JLt(9`X)`pthr9u#Mu`yc(dI zO4{2*ABpIYP1eR^L-C=lvAC$%RaDlHP40d^4)^O-38(0nz8KTCysAGLhsTD7NI>@w zaZ*RhX@%}c_iB&BSIFiWvOm2o@!j|kj);7`_Zr+!9uVM;Xg?S^n>!unbSj~0&9FN# zs-M)-fp8HJY$3>o_XB@qXI8-T@iJbDq>KfY6fum9VXU<>MpgpshAJ&fWXXyc?o4II z%0}RBBVz2Z07(&8n*lHV0?inpy4?{Y`^_vo0Cf~cvZ5>evL(7fOM8tP~*nZf0EDJvt)_JUqyFxM|*-T(3*+Y*01|GFQbjk1?m~@lczteWni9RRnJZQnm zU&Hj|;MnzphGQaO}9WTlJz@I2CAH;u%1IGMFht!`}2!&?xc(2L} zO3$Bt|7d-9;85S3{|U05_wDo_?+Z^mFBFO6LUEvnztbhZAROVr!*efauju34|8Z_) z<4f~DpI@Y#^F8owvqqk!pReoH6cS`#{VY#tD3i@ZBXTr@$LjF!is1BLeUD&#BKuC! z4YhUaaDEZDeaP{X_>i^cnRyRYOiS)%u4Pw-j&kT`8G`U7irE{t80j}l>E&HkfUqiZ YgPc{?Z+~07%IO`(>C2+O{