hotpatching of global map DAT file, fix bugs

This commit is contained in:
Ondřej Novák 2025-04-13 17:18:38 +02:00
parent 4fa01c46aa
commit 66edc652a1
11 changed files with 127 additions and 68 deletions

View file

@ -51,6 +51,8 @@ static void process_row(INI_CONFIG_SECTION *sec, const char *row) {
ini_replace_key(sec, "default_map", value); ini_replace_key(sec, "default_map", value);
} else if (istrcmp(key, "PATCH_FILE") == 0) { } else if (istrcmp(key, "PATCH_FILE") == 0) {
ini_replace_key(sec, "patch_file", file_icase_find(value)); ini_replace_key(sec, "patch_file", file_icase_find(value));
} else if (istrcmp(key, "PATCH") == 0 && istrcmp(value,"1") == 0) {
ini_replace_key(sec, "patch_mode", "1");
} }
} }

View file

@ -112,6 +112,7 @@ static char convert_book(const char *target_path) {
static char convert_end_titles(const char *target_path) { static char convert_end_titles(const char *target_path) {
const char *path = build_pathname(2, target_path, "end_titles.txt"); const char *path = build_pathname(2, target_path, "end_titles.txt");
path = local_strdup(path); path = local_strdup(path);
return convert_file_to(build_pathname(2, gpathtable[SR_DATA], "titulky.txt"), path); return convert_file_to(build_pathname(2, gpathtable[SR_DATA], "titulky.txt"), path);
} }
@ -120,6 +121,18 @@ static char convert_epilog(const char *target_path) {
path = local_strdup(path); path = local_strdup(path);
return convert_file_to(build_pathname(2, gpathtable[SR_DATA], "endtext.txt"), path); return convert_file_to(build_pathname(2, gpathtable[SR_DATA], "endtext.txt"), path);
} }
static char convert_intro_titles(const char *target_path) {
TSTR_LIST lst = create_list(100);
int err = load_string_list_ex(&lst, build_pathname(2, gpathtable[SR_VIDEO], "intro.txt"));
if (err) {
release_list(lst);
fprintf(stderr,"Failed to read: %s, error code: %d\n","intro.txt", err);
return 1;
}
err = store_to_csv(lst, build_pathname(2, target_path, "intro.csv"));
release_list(lst);
return err;
}
char generate_items_strings(const char *path) { char generate_items_strings(const char *path) {
load_items(); load_items();
@ -144,6 +157,21 @@ char generate_spell_strings(const char *path) {
return r; return r;
} }
extern TSHOP **shop_list;
extern int max_shops;
char generate_shop_strings(const char *path) {
TSTR_LIST lst = create_list(255);
load_shops();
for (int i = 0; i< max_shops; ++i) {
str_replace(&lst, shop_list[i]->shop_id, shop_list[i]->keeper);
}
int r = store_to_csv(lst, build_pathname(2,path,"shops.csv"));
release_list(lst);
return r;
}
char generate_dialog_append_pgf(TSTR_LIST *lst,const char *beg, const char *pc, const char *end) { char generate_dialog_append_pgf(TSTR_LIST *lst,const char *beg, const char *pc, const char *end) {
while (pc < end) { while (pc < end) {
@ -194,6 +222,8 @@ char generate_string_tables(const char *path) {
if (!generate_items_strings(path)) return 0; if (!generate_items_strings(path)) return 0;
if (!generate_spell_strings(path)) return 0; if (!generate_spell_strings(path)) return 0;
if (!generate_dialog_table(path)) return 0; if (!generate_dialog_table(path)) return 0;
if (!convert_intro_titles(path)) return 0;
if (!generate_shop_strings(path)) return 0;
return 1; return 1;
} }

View file

@ -261,6 +261,7 @@ static __inline int rangrnd(int a, int b) {return rnd(b-a+1)+a;}
#define H_KREVMID 184 #define H_KREVMID 184
#define H_KREVMAX 185 #define H_KREVMAX 185
#define H_ARMAGED 186 #define H_ARMAGED 186
#define H_GLOBMAP 200
#define H_ARMA_CNT 13 #define H_ARMA_CNT 13
#define H_FIRST_FREE 225 #define H_FIRST_FREE 225
#define H_MENUS_FREE 32768 #define H_MENUS_FREE 32768

View file

@ -46,7 +46,7 @@ static uint8_t last_index=1;
static int usemap; static int usemap;
static FILE *glbm; static TMPFILE_RD *glbm;
static char oddelovace[]=ODDELOVACE; static char oddelovace[]=ODDELOVACE;
static int last_oddelovac; static int last_oddelovac;
static int linecounter=0; static int linecounter=0;
@ -58,7 +58,7 @@ static char *symbolmap[]=
"D BREAK", "D BREAK",
"O CURMAP", // krit "O CURMAP", // krit
"E DRAW", "E DRAW",
"F ESCAPE", // "F ESCAPE",
"G FLG", // krit "G FLG", // krit
"P IFDEF", // krit "P IFDEF", // krit
"I INDX", "I INDX",
@ -83,7 +83,7 @@ static char *symbolmap[]=
#define OP_FLG 'G' #define OP_FLG 'G'
#define OP_USEMAP 'N' #define OP_USEMAP 'N'
#define OP_BREAK 'D' #define OP_BREAK 'D'
#define OP_ESCAPE 'F' //#define OP_ESCAPE 'F'
#define OP_CURMAP 'O' #define OP_CURMAP 'O'
#define OP_ISDEF 'P' #define OP_ISDEF 'P'
#define OP_SEKTOR 'Q' #define OP_SEKTOR 'Q'
@ -92,7 +92,8 @@ static char *symbolmap[]=
static char cti_int_num(int *readed) static char cti_int_num(int *readed)
{ {
return !fscanf(glbm,"%d",readed); //return !fscanf(glbm,"%d",readed);
return temp_storage_scanf(glbm, "%d", readed)<1;
} }
static int find_symbol(char **symbolmap,int list_len,int offset,char *symbol) static int find_symbol(char **symbolmap,int list_len,int offset,char *symbol)
@ -130,13 +131,13 @@ static int cti_oddelovac(void)//cte prvni oddelovac - preskakuje mezery
int c; int c;
do do
{ {
c=getc(glbm); c=temp_storage_getc(glbm);
if (c==OD_COMMENT) while((c=getc(glbm))!='\n'); if (c==OD_COMMENT) while((c=temp_storage_getc(glbm))!='\n');
if (c=='\n') linecounter++; if (c=='\n') linecounter++;
if (strchr(oddelovace,c)!=NULL || c==EOF) return c; if (strchr(oddelovace,c)!=NULL || c==EOF) return c;
} }
while (c==' ' || c=='\x9'); while (c==' ' || c=='\x9');
ungetc(c,glbm); temp_storage_ungetc(glbm);
return 0; return 0;
} }
@ -147,9 +148,9 @@ static int cti_retezec(int znaku,char *text,char mezera,char upcase)
znaku--; znaku--;
if (mezera) if (mezera)
{ {
while((c=getc(glbm))==32 || c==9); while((c=temp_storage_getc(glbm))==32 || c==9);
} }
else c=getc(glbm); else c=temp_storage_getc(glbm);
while (strchr(oddelovace,c)==NULL && ((c!=32 && c!=9) || !mezera) && c!=EOF) while (strchr(oddelovace,c)==NULL && ((c!=32 && c!=9) || !mezera) && c!=EOF)
{ {
if (upcase) c=toupper(c); if (upcase) c=toupper(c);
@ -158,9 +159,9 @@ static int cti_retezec(int znaku,char *text,char mezera,char upcase)
*text++=c; *text++=c;
znaku--; znaku--;
} }
c=getc(glbm); c=temp_storage_getc(glbm);
} }
if (c!=32 && c!=9) ungetc(c,glbm); if (c!=32 && c!=9) temp_storage_ungetc(glbm);
*text=0; *text=0;
return 0; return 0;
} }
@ -324,14 +325,14 @@ static char proved_prikaz()
if (usemap==-1) def_handle(usemap=end_ptr++,file,pcx_8bit_nopal,SR_DIALOGS); if (usemap==-1) def_handle(usemap=end_ptr++,file,pcx_8bit_nopal,SR_DIALOGS);
} }
break; break;
case OP_ESCAPE: /* case OP_ESCAPE:
{ {
cti_retezec(20,prikaz,1,1); cti_retezec(20,prikaz,1,1);
fclose(glbm); temp_storage_close_rd(glbm);
const char *s = build_pathname(2, gpathtable[SR_MAP], prikaz); const char *s = build_pathname(2, gpathtable[SR_MAP], prikaz);
if ((glbm=fopen_icase(s,"r"))==NULL) error(s); if ((glbm=fopen_icase(s,"r"))==NULL) error(s);
return 0; return 0;
} }*/
default:error(prikaz); default:error(prikaz);
} }
ODD=cti_oddelovac(); ODD=cti_oddelovac();
@ -373,10 +374,15 @@ static void do_script(void)
char vysledek; char vysledek;
const char *script = (const char *)ablock(H_GLOBMAP);
glbm=temp_storage_from_string(script);
/*
const char *s=build_pathname(2,gpathtable[SR_MAP], GLOBMAP); const char *s=build_pathname(2,gpathtable[SR_MAP], GLOBMAP);
linecounter=0; linecounter=0;
glbm=fopen_icase(s,"r"); glbm=fopen_icase(s,"r");
if (glbm==NULL) error("Chyb<EFBFBD> uveden<65> soubor..."); if (glbm==NULL) error("Chyb<EFBFBD> uveden<65> soubor...");
*/
ODD=cti_oddelovac(); ODD=cti_oddelovac();
do do
{ {
@ -394,7 +400,7 @@ static void do_script(void)
ODD=cti_oddelovac(); ODD=cti_oddelovac();
} }
while(ODD!=EOF); while(ODD!=EOF);
fclose(glbm); temp_storage_close_rd(glbm);
} }

View file

@ -89,7 +89,7 @@ THUMAN postavy[POCET_POSTAV],postavy_save[POCET_POSTAV];
void (*unwire_proc)(void); void (*unwire_proc)(void);
void (*wire_proc)(void); void (*wire_proc)(void);
char cur_mode,battle_mode; char cur_mode,battle_mode;
static char titles_on=0;
const void *pcx_fade_decomp(const void *p, int32_t *s, int h); const void *pcx_fade_decomp(const void *p, int32_t *s, int h);
const void *pcx_15bit_decomp(const void *p, int32_t *s, int h); const void *pcx_15bit_decomp(const void *p, int32_t *s, int h);
@ -97,6 +97,8 @@ const void *pcx_15bit_decomp_transp0(const void *p, int32_t *s, int h);
const void *pcx_15bit_autofade(const void *p, int32_t *s, int h); const void *pcx_15bit_autofade(const void *p, int32_t *s, int h);
const void *pcx_15bit_backgrnd(const void *p, int32_t *s, int h); const void *pcx_15bit_backgrnd(const void *p, int32_t *s, int h);
const void *pcx_8bit_decomp(const void *p, int32_t *s, int h); const void *pcx_8bit_decomp(const void *p, int32_t *s, int h);
const void *pcx_fade_decomp(const void *p, int32_t *s, int h);
const void *load_text_decomp(const void *p, int32_t *s, int h);
const char *texty_knihy; const char *texty_knihy;
static const char *patch_file=NULL; static const char *patch_file=NULL;
@ -219,7 +221,7 @@ TDREGISTERS registred[]=
{H_KREVMIN,"krevmin.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_KREVMIN,"krevmin.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_KREVMID,"krevmid.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_KREVMID,"krevmid.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_KREVMAX,"krevmax.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_KREVMAX,"krevmax.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_GLOBMAP,"globmap.dat",load_text_decomp, SR_MAP}
}; };
INIS sinit[]= INIS sinit[]=
@ -374,6 +376,13 @@ const void *hi_8bit_correct(const void *p,int32_t *s, int h)
return out; return out;
} }
const void *load_text_decomp(const void *p, int32_t *s, int h) {
char *newbuff = malloc(*s+1);
memcpy(newbuff,p, *s);
newbuff[*s] = 0;
(*s)+=1;
return newbuff;
}
const void *load_mob_legacy_format_direct(const void *p, int32_t *s, int h) { const void *load_mob_legacy_format_direct(const void *p, int32_t *s, int h) {
const char *c = p; const char *c = p;
@ -1316,22 +1325,14 @@ void play_movie_seq(const char *s,int y)
void play_anim(int anim_num) void play_anim(int anim_num)
{ {
char *t,*z;
TSTR_LIST titl=NULL; TSTR_LIST titl=NULL;
const char *s = build_pathname(2,gpathtable[SR_VIDEO], texty[anim_num]); const char *s = build_pathname(2,gpathtable[SR_VIDEO], texty[anim_num]);
s = local_strdup(s); s = local_strdup(s);
if (titles_on) char *n = set_file_extension(s, ".TXT");
{ if (load_string_list_ex(&titl,n)) titl=NULL;
concat(t,s," "); else {
z=strrchr(t,'.'); lang_patch_stringtable(&titl, "intro", "");
if (z!=NULL)
{
strcpy(z,".TXT");
if (load_string_list_ex(&titl,t)) titl=NULL;
} }
else titl=NULL;
}
else titl=NULL;
set_title_list(titl);set_font(H_FBIG,RGB(200,200,200)); set_title_list(titl);set_font(H_FBIG,RGB(200,200,200));
curcolor=0;bar32(0,0,639,459); curcolor=0;bar32(0,0,639,459);
showview(0,0,0,0); showview(0,0,0,0);
@ -1652,6 +1653,9 @@ const char *configure_pathtable(const INI_CONFIG *cfg) {
strcopy_n(default_map, defmap, sizeof(default_map)); strcopy_n(default_map, defmap, sizeof(default_map));
} }
patch_file = ini_get_string(paths, "patch_file", NULL); patch_file = ini_get_string(paths, "patch_file", NULL);
if (ini_get_boolean(paths, "patch_mode", 0)) {
mman_patch = 1;
}
return groot; return groot;
} }

View file

@ -5,6 +5,7 @@
#include <string_view> #include <string_view>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <cstring>
extern "C" { extern "C" {
#include "temp_storage.h" #include "temp_storage.h"
@ -162,3 +163,7 @@ int temp_storage_internal_end_scanf(TMPFILE_RD *f, int r) {
void temp_storage_ungetc(TMPFILE_RD *f) { void temp_storage_ungetc(TMPFILE_RD *f) {
f->_data = {f->_data.data()-1, f->_data.size()+1}; f->_data = {f->_data.data()-1, f->_data.size()+1};
} }
TMPFILE_RD *temp_storage_from_string(const char *content) {
return new TMPFILE_RD{{content, std::strlen(content)}};
}

View file

@ -15,6 +15,7 @@ typedef struct _temp_storage_file_rd TMPFILE_RD;
typedef struct _temp_storage_file_wr TMPFILE_WR; typedef struct _temp_storage_file_wr TMPFILE_WR;
TMPFILE_RD *temp_storage_open(const char *name); TMPFILE_RD *temp_storage_open(const char *name);
TMPFILE_RD *temp_storage_from_string(const char *content);
TMPFILE_WR *temp_storage_create(const char *name); TMPFILE_WR *temp_storage_create(const char *name);
TMPFILE_WR *temp_storage_append(const char *name); TMPFILE_WR *temp_storage_append(const char *name);
void temp_storage_delete(const char *name); void temp_storage_delete(const char *name);

View file

@ -195,7 +195,7 @@ int get_file_entry_in_table(const TNAMETABLE_REF *where, char *name) {
char get_file_entry(int group,char *name, THANDLE_DATA *h) { char get_file_entry(int group,char *name, THANDLE_DATA *h) {
char ex; char ex;
ex=test_file_exist_DOS(group,name); ex=mman_patch && test_file_exist_DOS(group,name);
if (!ex) { if (!ex) {
for (int i = 0; i < MAX_PATCHES; ++i) { for (int i = 0; i < MAX_PATCHES; ++i) {
const TDDLMAP_INFO *nfo = &ddlmap[i]; const TDDLMAP_INFO *nfo = &ddlmap[i];

View file

@ -7,6 +7,7 @@
#include "mgifmem.h" #include "mgifmem.h"
#include <platform/sound.h> #include <platform/sound.h>
#include "strlite.h"
@ -89,35 +90,38 @@ static void StretchImageHQ(word *src, word *trg, int32_t linelen, char full)
trg_row += 2*linelen; trg_row += 2*linelen;
} }
#if 0
int x,y; }
src+=3;
for (y=0,s=src,t=trg;y<ys;y++,t+=linelen*2,s+=xs) static TSTR_LIST titles;
for (x=0;x<xs;x++)
static void show_title(int frame)
{
int y,yt,h;
static int lasty = 478;
char *c;
if (frame<2) lasty=478;
if (frame >= str_count(titles)) return;
if (titles[frame]==NULL) return;
h=text_height(titles[frame])+2;
yt=y=479-2*h;
curcolor=0;
bar32(0,lasty,639,479);
c=strchr(titles[frame],'\n');
if (c!=NULL) *c=0;
set_aligned_position(320,y,1,0,titles[frame]);
outtext(titles[frame]);
if (c!=NULL)
{ {
word val; *c='\n';c++;y+=h;
t[x*2]=s[x]+(s[x]&0x7fe0); set_aligned_position(320,y,1,0,c);
if (x) outtext(c);
{
val=((s[x-1] & 0x7bde)+(s[x] & 0x7bde))>>1;
t[x*2-1]=val+(val&0x7fe0);
}
if (full)
{
if (y)
{
val=((s[x-xs] & 0x7bde)+(s[x] & 0x7bde))>>1;
t[x*2-linelen]=val+(val&0x7fe0);
}
if (x && y)
{
val=((s[x-xs-1] & 0x7bde)+(s[x] & 0x7bde))>>1;
t[x*2-linelen-1]=val+(val&0x7fe0);
}
}
}
#endif
} }
if (lasty<yt) y=lasty;else y=yt;
showview(0,y,640,480-y);
lasty=yt;
}
@ -143,6 +147,7 @@ static void PlayMGFFile(const void *file, MGIF_PROC proc,int ypos,char full)
f=mgif_play(file); f=mgif_play(file);
StretchImageHQ(picture, GetScreenAdr()+ypos*scr_linelen2, scr_linelen2,full); StretchImageHQ(picture, GetScreenAdr()+ypos*scr_linelen2, scr_linelen2,full);
showview(0,ypos,0,360); showview(0,ypos,0,360);
if (titles) show_title(hdr->cur_frame);
if (game_display_is_quit_requested()) { if (game_display_is_quit_requested()) {
break; break;
} else if (_bios_keybrd(_KEYBRD_READY)) { } else if (_bios_keybrd(_KEYBRD_READY)) {
@ -187,10 +192,11 @@ void play_animation(const char *filename,char mode,int posy,char sound)
unmap_file(mgf, sz); unmap_file(mgf, sz);
} }
void set_title_list(char **titles) void set_title_list(char **title_list)
{ {
titles=title_list;
} }
void set_play_attribs(void *screen,char rdraw,char bm,char colr64) void set_play_attribs(void *screen,char rdraw,char bm,char colr64)
{ {

View file

@ -52,7 +52,7 @@ int main(int argc, char **argv) {
}; };
cfg.adventure_path = adv_config_file.empty()?NULL:adv_config_file.c_str(); cfg.adventure_path = adv_config_file.empty()?NULL:adv_config_file.c_str();
cfg.config_path = config_name.c_str(); cfg.config_path = config_name.c_str();
cfg.lang_path = lang.c_str(); cfg.lang_path = lang.empty()?NULL:lang.c_str();
try { try {
if (!gen_stringtable_path.empty()) { if (!gen_stringtable_path.empty()) {

View file

@ -1,6 +1,8 @@
extern "C" { extern "C" {
#include "map_file.h" #include "map_file.h"
#include "../error.h"
} }
#include <stdio.h> #include <stdio.h>
@ -9,6 +11,8 @@ extern "C" {
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include <errno.h>
// Funkce pro mapování souboru do paměti // Funkce pro mapování souboru do paměti
void* map_file_to_memory(const char *name, size_t *sz) { void* map_file_to_memory(const char *name, size_t *sz) {
@ -19,14 +23,14 @@ void* map_file_to_memory(const char *name, size_t *sz) {
// Otevření souboru pro čtení // Otevření souboru pro čtení
int fd = open(name, O_RDONLY); int fd = open(name, O_RDONLY);
if (fd == -1) { if (fd == -1) {
perror("Chyba při otevírání souboru"); display_error("Failed to open file: %s %s", name, strerror(errno));
return NULL; return NULL;
} }
// Získání velikosti souboru // Získání velikosti souboru
struct stat st; struct stat st;
if (fstat(fd, &st) == -1) { if (fstat(fd, &st) == -1) {
perror("Chyba při získávání velikosti souboru"); display_error("Failed to fstat file: %s %s", name, strerror(errno));
close(fd); close(fd);
return NULL; return NULL;
} }
@ -35,7 +39,7 @@ void* map_file_to_memory(const char *name, size_t *sz) {
// Namapování souboru do paměti // Namapování souboru do paměti
void *mapped = mmap(NULL, *sz, PROT_READ, MAP_PRIVATE, fd, 0); void *mapped = mmap(NULL, *sz, PROT_READ, MAP_PRIVATE, fd, 0);
if (mapped == MAP_FAILED) { if (mapped == MAP_FAILED) {
perror("Chyba při mapování souboru"); display_error("Failed to map file: %s %s", name, strerror(errno));
close(fd); close(fd);
return NULL; return NULL;
} }