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;
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;
else view=pos*16+(p->anim_counter % (MAX(p->anim_counts[pos],1)))+1;
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)
{
TMPFILE_RD *f;
void *temp;
const void *temp;
int sect;
int32_t size,r;
uint32_t size,r;
char nmapend=1;
@ -130,28 +130,30 @@ int load_org_map(const char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT
switch (sect)
{
case A_SIDEMAP:
*sides=temp;
*sides=getmem(size);
memcpy(*sides,temp,size);
break;
case A_SECTMAP:
*sectors=temp;
*sectors=getmem(size);
memcpy(*sectors,temp,size);
if (mapsize!=NULL) *mapsize=size/sizeof(TSECTOR);
break;
case A_MAPINFO:
if (coords!=NULL) *coords=temp;else free(temp);
if (coords!=NULL) {
*coords=getmem(size);
memcpy(*coords,temp,size);
}
break;
case A_MAPGLOB:
//memcpy(&mglob,temp,min(sizeof(mglob),size));
free(temp);
break;
case A_MAPEND :
nmapend=0;
free(temp);
break;
default: free(temp);
default: break;
}
else
{
if (temp!=NULL)free(temp);
temp_storage_close_rd(f);
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);
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_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);
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 draw_medium_map(void);
void anim_sipky(int h,int mode);
@ -833,7 +833,7 @@ extern short water_breath; //vec pro dychani pod vodou
extern short flute_item;
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);
#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 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_ex(int side,int flags, int runatsect);
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 mute_all_tracks(char all);
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 start_play_flute(char );
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);
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
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;
void send_mob_to(int m,word *path);
void save_enemy_paths(TMPFILE_WR *f);

View file

@ -151,8 +151,8 @@ void load_items()
{
TMPFILE_RD *f;
int sect,i,hs;
int32_t size;
void *p;
uint32_t size;
const void *p;
f=NULL;i=0;
ikon_libs=hl_ptr;
@ -182,22 +182,20 @@ void load_items()
case 4:
face_arr[sect-1]=hl_ptr-1;
prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS);
free(p);
break;
case 2:
case 3:
face_arr[sect-1]=hl_ptr-1;
prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS);
free(p);
break;
case 5:
face_arr[sect-1]=hl_ptr-1;
prepare_graphics(&hl_ptr,(char *)p,size,NULL,SR_ITEMS);
free(p);
break;
case SV_ITLIST:
glob_items=p;
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) {
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);
@ -208,10 +206,8 @@ void load_items()
hs=hl_ptr;
prepare_graphics(&hl_ptr,(char *)p,size,soundfx_load,SR_ZVUKY);
sound_handle=hs-1;
free(p);
break;
default:
free(p);
break;
}
}
@ -374,7 +370,7 @@ short create_item_money(int obnos)
return i+1;
}
void load_item_map(void *p,int32_t s)
void load_item_map(const void *p,uint32_t s)
{
word itmc;
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_m = 0;
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) {
int32_t s;
uint32_t load_section_mem(TMPFILE_RD *f,const void **section, int *sct_type,uint32_t *sect_size) {
uint32_t s;
char c[20];
*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;
temp_storage_read(sct_type,sizeof(*sct_type),f);
temp_storage_read(sect_size,sizeof(*sect_size),f);
temp_storage_read(&s,sizeof(s),f);
*section=getmem(*sect_size);
s=temp_storage_read(*section,*sect_size,f);
temp_storage_read(&s,sizeof(s),f); //unused
*section = temp_storage_get_binary(f, *sect_size, &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;
end=names+size;
p=names;
while (p<end)
{
def_handle(*ofs,p,decomp,class);
def_handle(*ofs,p,decomp,cls);
p=strchr(p,'\0');
p++;
(*ofs)++;
@ -261,9 +260,9 @@ void translate_map_name(const char *mapfile, MAPGLOBAL *mglob) {
int load_map(const char *filename)
{
TMPFILE_RD *f;
void *temp;
const void *temp;
int sect;
int32_t size,r;
uint32_t size;
char nmapend=1;
int ofsts=START_HANDLE;
char snd_load=0;
@ -285,67 +284,61 @@ int load_map(const char *filename)
if (f==NULL) return -1;
do
{
r=load_section_mem(f,&temp,&sect,&size);
uint32_t r=load_section_mem(f,&temp,&sect,&size);
if (r==size)
switch (sect)
{
case A_SIDEMAP:
map_sides=temp;
map_sides = getmem(size);
memcpy(map_sides, temp, size);
break;
case A_SECTMAP:
map_sectors=temp;
map_sectors = getmem(size);
memcpy(map_sectors, temp, size);
break;
case A_MAPINFO:
map_coord=temp;
map_coord = getmem(size);
memcpy(map_coord, temp, size);
mapsize=size / sizeof(TMAP_EDIT_INFO);
init_items();
init_mobs();
break;
case A_MAPEND:
nmapend=0;
free(temp);
break;
case A_STRMAIN:
num_ofsets[MAIN_NUM]=ofsts-1;
num_ofsets_count[MAIN_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break;
case A_STRLEFT:
num_ofsets[LEFT_NUM]=ofsts-1;
num_ofsets_count[LEFT_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break;
case A_STRRIGHT:
num_ofsets[RIGHT_NUM]=ofsts-1;
num_ofsets_count[RIGHT_NUM] = prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break;
case A_STRCEIL:
num_ofsets[CEIL_NUM]=ofsts-1;
num_ofsets_count[CEIL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA);
free(temp);
break;
case A_STRFLOOR:
num_ofsets[FLOOR_NUM]=ofsts-1;
num_ofsets_count[FLOOR_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA);
free(temp);
break;
case A_STRARC:
num_ofsets[OBL_NUM]=ofsts-1;
num_ofsets_count[OBL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break;
case A_STRARC2:
num_ofsets[OBL2_NUM]=ofsts-1;
num_ofsets_count[OBL2_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp);
break;
case A_MAPGLOB:
num_ofsets[BACK_NUM]=ofsts;
num_ofsets_count[BACK_NUM]=1;
memset(&mglob,0,sizeof(mglob));
memcpy(&mglob,temp,MIN((int)size,(int)sizeof(mglob)));
free(temp);
for(r=0;r<4;r++) {
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:
SEND_LOG("(GAME) Loading items...");
load_item_map(temp,size);
free(temp);
break;
case A_MAPMOBS:
if (snd_load==0) create_sound_table_old();
@ -377,39 +369,36 @@ int load_map(const char *filename)
mob_template=NULL;
SEND_LOG("(GAME) Loading enemies from map template...");
}
free(temp);
break;
case A_MAPMACR:
SEND_LOG("(GAME) Loading multiactions...");
load_macros(size,temp);
free(temp);
break;
case A_MAPVYK:
map_vyk=temp;
map_vyk = getmem(size);
memcpy(map_vyk, temp, size);
vyk_max=size/sizeof(TVYKLENEK);
break;
case A_MOBS:
mob_template=load_mob_legacy_format_direct(temp, &size,0);
mob_size=size;
free(temp);
case A_MOBS: {
int32_t s = size;
mob_template=load_mob_legacy_format_direct(temp, &s,0);
mob_size=s;
break;
}
case A_MOBSND:
snd_load=1;
create_sound_table(temp,size);
free(temp);
break;
case A_PASSW :
map_with_password=1;
free(temp);
break;
default:free(temp);
default:break;
}
else
{
if (temp!=NULL)free(temp);
ablock_free(mob_template);
temp_storage_close_rd(f);
return -3;
@ -429,7 +418,7 @@ int load_map(const char *filename)
}
init_tracks();
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)
{
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;
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());
}
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) {
auto &d = f->_data;
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);
uint32_t temp_storage_read(void *data, uint32_t 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);
#ifdef _MSC_VER