load_section_mem now uses zero copy to receive binary data

This commit is contained in:
Ondřej Novák 2025-07-10 10:08:19 +02:00
parent 9a41bc0f67
commit 3463d8e720
9 changed files with 71 additions and 67 deletions

View file

@ -355,7 +355,7 @@ static void mob_sound_event(TMOB *m, int event) {
} }
} }
void load_enemies(short *data,int size,int *grptr,const TMOB *template,int32_t tsize) void load_enemies(const short *data,int size,int *grptr,const TMOB *template,int32_t tsize)
{ {
int i; int i;
short cisla[256]; short cisla[256];
@ -948,7 +948,7 @@ TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir)
} }
} }
} }
if (pos==3) ret.mirror=pos=1; if (pos==3) ret.mirror=1;
if (p->anim_counter==-1) view=pos*16; if (p->anim_counter==-1) view=pos*16;
else view=pos*16+(p->anim_counter % (MAX(p->anim_counts[pos],1)))+1; else view=pos*16+(p->anim_counter % (MAX(p->anim_counts[pos],1)))+1;
ret.face = view; ret.face = view;

View file

@ -114,9 +114,9 @@ static void unable_write_temp(char *c)
int load_org_map(const char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT_INFO **coords,int *mapsize) int load_org_map(const char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT_INFO **coords,int *mapsize)
{ {
TMPFILE_RD *f; TMPFILE_RD *f;
void *temp; const void *temp;
int sect; int sect;
int32_t size,r; uint32_t size,r;
char nmapend=1; char nmapend=1;
@ -130,28 +130,30 @@ int load_org_map(const char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT
switch (sect) switch (sect)
{ {
case A_SIDEMAP: case A_SIDEMAP:
*sides=temp; *sides=getmem(size);
memcpy(*sides,temp,size);
break; break;
case A_SECTMAP: case A_SECTMAP:
*sectors=temp; *sectors=getmem(size);
memcpy(*sectors,temp,size);
if (mapsize!=NULL) *mapsize=size/sizeof(TSECTOR); if (mapsize!=NULL) *mapsize=size/sizeof(TSECTOR);
break; break;
case A_MAPINFO: case A_MAPINFO:
if (coords!=NULL) *coords=temp;else free(temp); if (coords!=NULL) {
*coords=getmem(size);
memcpy(*coords,temp,size);
}
break; break;
case A_MAPGLOB: case A_MAPGLOB:
//memcpy(&mglob,temp,min(sizeof(mglob),size)); //memcpy(&mglob,temp,min(sizeof(mglob),size));
free(temp);
break; break;
case A_MAPEND : case A_MAPEND :
nmapend=0; nmapend=0;
free(temp);
break; break;
default: free(temp); default: break;
} }
else else
{ {
if (temp!=NULL)free(temp);
temp_storage_close_rd(f); temp_storage_close_rd(f);
return -1; return -1;
} }

View file

@ -756,9 +756,9 @@ void a_touch(int sector,int dir);
int do_action(int action_numb,int sector,int direct,int flags,int nosend); int do_action(int action_numb,int sector,int direct,int flags,int nosend);
void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay); void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay);
//int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size); //int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size);
int32_t load_section_mem(TMPFILE_RD *f,void **section, int *sct_type,int32_t *sect_size); uint32_t load_section_mem(TMPFILE_RD *f,const void **section, int *sct_type,uint32_t *sect_size);
TMPFILE_RD *open_ddl_file(const char *name, int group); TMPFILE_RD *open_ddl_file(const char *name, int group);
int prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class); int prepare_graphics(int *ofs,const char *names,int32_t size,ABLOCK_DECODEPROC decomp,int cls);
void show_automap(char full); void show_automap(char full);
void draw_medium_map(void); void draw_medium_map(void);
void anim_sipky(int h,int mode); void anim_sipky(int h,int mode);
@ -833,7 +833,7 @@ extern short water_breath; //vec pro dychani pod vodou
extern short flute_item; extern short flute_item;
void load_items(void); void load_items(void);
void load_item_map(void *p,int32_t s); void load_item_map(const void *p,uint32_t s);
void draw_placed_items_normal(int celx,int cely,int sect,int side); void draw_placed_items_normal(int celx,int cely,int sect,int side);
#define SPL_INVIS 0x1 //hrac je neviditelny #define SPL_INVIS 0x1 //hrac je neviditelny
@ -1348,7 +1348,7 @@ extern TMULTI_ACTION_STATE macro_state_block;
extern void *macro_block; //alokovany blok maker (pri unloadu free!) extern void *macro_block; //alokovany blok maker (pri unloadu free!)
extern int macro_block_size; //velikost bloku; extern int macro_block_size; //velikost bloku;
void load_macros(int size,void *data); void load_macros(int size,const void *data);
void call_macro(int side,int flags); void call_macro(int side,int flags);
void call_macro_ex(int side,int flags, int runatsect); void call_macro_ex(int side,int flags, int runatsect);
char get_player_triggered(int p); //zjistuje zda hrac s cislem p byl makrem zasazen; char get_player_triggered(int p); //zjistuje zda hrac s cislem p byl makrem zasazen;
@ -1469,7 +1469,7 @@ char test_playing(int track);
void stop_track_free(int track); void stop_track_free(int track);
void mute_all_tracks(char all); void mute_all_tracks(char all);
void kill_all_sounds(void); void kill_all_sounds(void);
void create_sound_table(char *t,int32_t size); void create_sound_table(const char *t,int32_t size);
void create_sound_table_old(void); void create_sound_table_old(void);
void start_play_flute(char ); void start_play_flute(char );
void stop_play_flute(void); void stop_play_flute(void);
@ -1580,7 +1580,7 @@ char track_mob(int sect,int dir);//trackuje pritomnost potvory v urcitem smeru
void stop_all_mobs(void); void stop_all_mobs(void);
int utok_na_sektor(THUMAN *p,TMOB *m,int chaos,int bonus, int ruka); int utok_na_sektor(THUMAN *p,TMOB *m,int chaos,int bonus, int ruka);
int vyber_potvoru(int sect,int dir,int *chaos); //vybere potvoru ze sektoru a smeru. Vraci take pocet potvor v promenne *chaos int vyber_potvoru(int sect,int dir,int *chaos); //vybere potvoru ze sektoru a smeru. Vraci take pocet potvor v promenne *chaos
void load_enemies(short *data,int size,int *grptr,const TMOB *template,int32_t tsize); void load_enemies(const short *data,int size,int *grptr,const TMOB *template,int32_t tsize);
char mob_test_na_bitvu(TMOB *p); //nastavi p->vlajky|MOB_INBATTLE pokud potvora muze vstoupit do bitvy; char mob_test_na_bitvu(TMOB *p); //nastavi p->vlajky|MOB_INBATTLE pokud potvora muze vstoupit do bitvy;
void send_mob_to(int m,word *path); void send_mob_to(int m,word *path);
void save_enemy_paths(TMPFILE_WR *f); void save_enemy_paths(TMPFILE_WR *f);

View file

@ -151,8 +151,8 @@ void load_items()
{ {
TMPFILE_RD *f; TMPFILE_RD *f;
int sect,i,hs; int sect,i,hs;
int32_t size; uint32_t size;
void *p; const void *p;
f=NULL;i=0; f=NULL;i=0;
ikon_libs=hl_ptr; ikon_libs=hl_ptr;
@ -182,22 +182,20 @@ void load_items()
case 4: case 4:
face_arr[sect-1]=hl_ptr-1; face_arr[sect-1]=hl_ptr-1;
prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS); prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS);
free(p);
break; break;
case 2: case 2:
case 3: case 3:
face_arr[sect-1]=hl_ptr-1; face_arr[sect-1]=hl_ptr-1;
prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS); prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS);
free(p);
break; break;
case 5: case 5:
face_arr[sect-1]=hl_ptr-1; face_arr[sect-1]=hl_ptr-1;
prepare_graphics(&hl_ptr,(char *)p,size,NULL,SR_ITEMS); prepare_graphics(&hl_ptr,(char *)p,size,NULL,SR_ITEMS);
free(p);
break; break;
case SV_ITLIST: case SV_ITLIST:
glob_items=p; it_count_orgn=item_count = size/sizeof(TITEM);
it_count_orgn=item_count=size/sizeof(TITEM); glob_items=NewArr(TITEM, item_count);;
memcpy(glob_items, p, sizeof(TITEM)*item_count);
for (int i = 0; i < it_count_orgn; ++i) { for (int i = 0; i < it_count_orgn; ++i) {
if (glob_items[i].cena_high != 0) { if (glob_items[i].cena_high != 0) {
SEND_LOG("(ITEMS) Over-priced item %i %s %d > 65535", i, glob_items[i].jmeno, glob_items[i].cena + 65536*glob_items[i].cena_high); SEND_LOG("(ITEMS) Over-priced item %i %s %d > 65535", i, glob_items[i].jmeno, glob_items[i].cena + 65536*glob_items[i].cena_high);
@ -208,10 +206,8 @@ void load_items()
hs=hl_ptr; hs=hl_ptr;
prepare_graphics(&hl_ptr,(char *)p,size,soundfx_load,SR_ZVUKY); prepare_graphics(&hl_ptr,(char *)p,size,soundfx_load,SR_ZVUKY);
sound_handle=hs-1; sound_handle=hs-1;
free(p);
break; break;
default: default:
free(p);
break; break;
} }
} }
@ -374,7 +370,7 @@ short create_item_money(int obnos)
return i+1; return i+1;
} }
void load_item_map(void *p,int32_t s) void load_item_map(const void *p,uint32_t s)
{ {
word itmc; word itmc;
int sect; int sect;

View file

@ -93,10 +93,10 @@ static void read_macro_item(const char *iter, size_t sz, TMULTI_ACTION *target)
} }
} }
void load_macros(int size,void *data) void load_macros(int size,const void *data)
{ {
char *iter = data; const char *iter = data;
size_t count_s = mapsize*4; size_t count_s = mapsize*4;
size_t count_m = 0; size_t count_m = 0;
size_t i; size_t i;

View file

@ -118,8 +118,8 @@ int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size)
} }
*/ */
int32_t load_section_mem(TMPFILE_RD *f,void **section, int *sct_type,int32_t *sect_size) { uint32_t load_section_mem(TMPFILE_RD *f,const void **section, int *sct_type,uint32_t *sect_size) {
int32_t s; uint32_t s;
char c[20]; char c[20];
*section=NULL; *section=NULL;
@ -127,23 +127,22 @@ int32_t load_section_mem(TMPFILE_RD *f,void **section, int *sct_type,int32_t *se
if (strcmp(c,sekceid)) return -1; if (strcmp(c,sekceid)) return -1;
temp_storage_read(sct_type,sizeof(*sct_type),f); temp_storage_read(sct_type,sizeof(*sct_type),f);
temp_storage_read(sect_size,sizeof(*sect_size),f); temp_storage_read(sect_size,sizeof(*sect_size),f);
temp_storage_read(&s,sizeof(s),f); temp_storage_read(&s,sizeof(s),f); //unused
*section=getmem(*sect_size); *section = temp_storage_get_binary(f, *sect_size, &s);
s=temp_storage_read(*section,*sect_size,f);
return s; return s;
} }
int prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class) int prepare_graphics(int *ofs,const char *names,int32_t size,ABLOCK_DECODEPROC decomp,int cls)
{ {
char *p,*end; const char *p,*end;
int count = 0; int count = 0;
end=names+size; end=names+size;
p=names; p=names;
while (p<end) while (p<end)
{ {
def_handle(*ofs,p,decomp,class); def_handle(*ofs,p,decomp,cls);
p=strchr(p,'\0'); p=strchr(p,'\0');
p++; p++;
(*ofs)++; (*ofs)++;
@ -261,9 +260,9 @@ void translate_map_name(const char *mapfile, MAPGLOBAL *mglob) {
int load_map(const char *filename) int load_map(const char *filename)
{ {
TMPFILE_RD *f; TMPFILE_RD *f;
void *temp; const void *temp;
int sect; int sect;
int32_t size,r; uint32_t size;
char nmapend=1; char nmapend=1;
int ofsts=START_HANDLE; int ofsts=START_HANDLE;
char snd_load=0; char snd_load=0;
@ -285,67 +284,61 @@ int load_map(const char *filename)
if (f==NULL) return -1; if (f==NULL) return -1;
do do
{ {
r=load_section_mem(f,&temp,&sect,&size); uint32_t r=load_section_mem(f,&temp,&sect,&size);
if (r==size) if (r==size)
switch (sect) switch (sect)
{ {
case A_SIDEMAP: case A_SIDEMAP:
map_sides=temp; map_sides = getmem(size);
memcpy(map_sides, temp, size);
break; break;
case A_SECTMAP: case A_SECTMAP:
map_sectors=temp; map_sectors = getmem(size);
memcpy(map_sectors, temp, size);
break; break;
case A_MAPINFO: case A_MAPINFO:
map_coord=temp; map_coord = getmem(size);
memcpy(map_coord, temp, size);
mapsize=size / sizeof(TMAP_EDIT_INFO); mapsize=size / sizeof(TMAP_EDIT_INFO);
init_items(); init_items();
init_mobs(); init_mobs();
break; break;
case A_MAPEND: case A_MAPEND:
nmapend=0; nmapend=0;
free(temp);
break; break;
case A_STRMAIN: case A_STRMAIN:
num_ofsets[MAIN_NUM]=ofsts-1; num_ofsets[MAIN_NUM]=ofsts-1;
num_ofsets_count[MAIN_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[MAIN_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break; break;
case A_STRLEFT: case A_STRLEFT:
num_ofsets[LEFT_NUM]=ofsts-1; num_ofsets[LEFT_NUM]=ofsts-1;
num_ofsets_count[LEFT_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[LEFT_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break; break;
case A_STRRIGHT: case A_STRRIGHT:
num_ofsets[RIGHT_NUM]=ofsts-1; num_ofsets[RIGHT_NUM]=ofsts-1;
num_ofsets_count[RIGHT_NUM] = prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[RIGHT_NUM] = prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break; break;
case A_STRCEIL: case A_STRCEIL:
num_ofsets[CEIL_NUM]=ofsts-1; num_ofsets[CEIL_NUM]=ofsts-1;
num_ofsets_count[CEIL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA); num_ofsets_count[CEIL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA);
free(temp);
break; break;
case A_STRFLOOR: case A_STRFLOOR:
num_ofsets[FLOOR_NUM]=ofsts-1; num_ofsets[FLOOR_NUM]=ofsts-1;
num_ofsets_count[FLOOR_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA); num_ofsets_count[FLOOR_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA);
free(temp);
break; break;
case A_STRARC: case A_STRARC:
num_ofsets[OBL_NUM]=ofsts-1; num_ofsets[OBL_NUM]=ofsts-1;
num_ofsets_count[OBL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[OBL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break; break;
case A_STRARC2: case A_STRARC2:
num_ofsets[OBL2_NUM]=ofsts-1; num_ofsets[OBL2_NUM]=ofsts-1;
num_ofsets_count[OBL2_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[OBL2_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break; break;
case A_MAPGLOB: case A_MAPGLOB:
num_ofsets[BACK_NUM]=ofsts; num_ofsets[BACK_NUM]=ofsts;
num_ofsets_count[BACK_NUM]=1; num_ofsets_count[BACK_NUM]=1;
memset(&mglob,0,sizeof(mglob)); memset(&mglob,0,sizeof(mglob));
memcpy(&mglob,temp,MIN((int)size,(int)sizeof(mglob))); memcpy(&mglob,temp,MIN((int)size,(int)sizeof(mglob)));
free(temp);
for(r=0;r<4;r++) { for(r=0;r<4;r++) {
def_handle(ofsts++,mglob.back_fnames[r],pcx_fade_decomp,SR_GRAFIKA); def_handle(ofsts++,mglob.back_fnames[r],pcx_fade_decomp,SR_GRAFIKA);
} }
@ -355,7 +348,6 @@ int load_map(const char *filename)
case A_MAPITEM: case A_MAPITEM:
SEND_LOG("(GAME) Loading items..."); SEND_LOG("(GAME) Loading items...");
load_item_map(temp,size); load_item_map(temp,size);
free(temp);
break; break;
case A_MAPMOBS: case A_MAPMOBS:
if (snd_load==0) create_sound_table_old(); if (snd_load==0) create_sound_table_old();
@ -377,39 +369,36 @@ int load_map(const char *filename)
mob_template=NULL; mob_template=NULL;
SEND_LOG("(GAME) Loading enemies from map template..."); SEND_LOG("(GAME) Loading enemies from map template...");
} }
free(temp);
break; break;
case A_MAPMACR: case A_MAPMACR:
SEND_LOG("(GAME) Loading multiactions..."); SEND_LOG("(GAME) Loading multiactions...");
load_macros(size,temp); load_macros(size,temp);
free(temp);
break; break;
case A_MAPVYK: case A_MAPVYK:
map_vyk=temp; map_vyk = getmem(size);
memcpy(map_vyk, temp, size);
vyk_max=size/sizeof(TVYKLENEK); vyk_max=size/sizeof(TVYKLENEK);
break; break;
case A_MOBS: case A_MOBS: {
mob_template=load_mob_legacy_format_direct(temp, &size,0); int32_t s = size;
mob_size=size; mob_template=load_mob_legacy_format_direct(temp, &s,0);
free(temp); mob_size=s;
break; break;
}
case A_MOBSND: case A_MOBSND:
snd_load=1; snd_load=1;
create_sound_table(temp,size); create_sound_table(temp,size);
free(temp);
break; break;
case A_PASSW : case A_PASSW :
map_with_password=1; map_with_password=1;
free(temp);
break; break;
default:free(temp); default:break;
} }
else else
{ {
if (temp!=NULL)free(temp);
ablock_free(mob_template); ablock_free(mob_template);
temp_storage_close_rd(f); temp_storage_close_rd(f);
return -3; return -3;
@ -429,7 +418,7 @@ int load_map(const char *filename)
} }
init_tracks(); init_tracks();
change_music(get_next_music_from_playlist()); change_music(get_next_music_from_playlist());
for(r=0;r<mapsize*4;r++) flag_map[r]=(char)map_sides[r].flags; for(int r=0;r<mapsize*4;r++) flag_map[r]=(char)map_sides[r].flags;
if (!doNotLoadMapState && load_map_state()==-2) if (!doNotLoadMapState && load_map_state()==-2)
{ {
closemode(); closemode();

View file

@ -640,9 +640,9 @@ void play_sample_at_channel(int sample,int channel,int vol)
} }
void create_sound_table(char *template,int32_t size) void create_sound_table(const char *template,int32_t size)
{ {
char *c,*s; const char *c,*s;
int i=0; int i=0;
if (sound_table==NULL) sound_table=create_list(2); if (sound_table==NULL) sound_table=create_list(2);

View file

@ -112,6 +112,15 @@ uint32_t temp_storage_read(void *data, uint32_t size, TMPFILE_RD *f) {
return static_cast<uint32_t>(p.size()); return static_cast<uint32_t>(p.size());
} }
const void *temp_storage_get_binary(TMPFILE_RD *f, uint32_t size, uint32_t *retrieved) {
auto &d = f->_data;
if (size > d.size()) size = d.size();
const void *ret = d.data();
d = d.substr(size);
*retrieved = size;
return ret;
}
void temp_storage_skip(TMPFILE_RD *f, int bytes) { void temp_storage_skip(TMPFILE_RD *f, int bytes) {
auto &d = f->_data; auto &d = f->_data;
auto p = d.substr(0,bytes); auto p = d.substr(0,bytes);

View file

@ -28,6 +28,14 @@ void temp_storage_ungetc(TMPFILE_RD *f);
void temp_storage_write(const void *data, uint32_t size, TMPFILE_WR *f); void temp_storage_write(const void *data, uint32_t size, TMPFILE_WR *f);
uint32_t temp_storage_read(void *data, uint32_t size, TMPFILE_RD *f); uint32_t temp_storage_read(void *data, uint32_t size, TMPFILE_RD *f);
uint32_t temp_storage_remain_size(TMPFILE_RD *f); uint32_t temp_storage_remain_size(TMPFILE_RD *f);
///retrievies pointer to underlying stream binary (zero copy)
/**
* @param f source file
* @param size requested size
* @param retrieved retrieved size
* @return pointer to retrieved data. It remains valid until the storage handle is closed
*/
const void *temp_storage_get_binary(TMPFILE_RD *f, uint32_t size, uint32_t *retrieved);
void temp_storage_skip(TMPFILE_RD *f, int bytes); void temp_storage_skip(TMPFILE_RD *f, int bytes);
#ifdef _MSC_VER #ifdef _MSC_VER