Skip to content

Commit

Permalink
prop comments
Browse files Browse the repository at this point in the history
add song_current
add DATA group for blob data
add ACTIVE_SONG, ACTIVE_SONG_NSF
  • Loading branch information
bbbradsmith committed Apr 25, 2024
1 parent 8f16795 commit 2e6e1c1
Show file tree
Hide file tree
Showing 7 changed files with 863 additions and 835 deletions.
1,460 changes: 732 additions & 728 deletions core/enums_data.h

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions core/nsfplaycore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ uint32_t nsfplay_song_count(const NSFCore* core)
return core->nsf_prop_int(NSF_PROP_ACTIVE_SONG_COUNT);
}

uint32_t nsfplay_song_current(const NSFCore* core)
{
return core->nsf_prop_int(NSF_PROP_ACTIVE_SONG);
}

bool nsfplay_song(NSFCore* core, uint8_t song)
{
(void)core;
Expand Down
2 changes: 2 additions & 0 deletions enums/english.txt
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ LOCALPROP NSF2_INIT_NORETURN "NSF2 Non-Returning INIT"
LOCALPROP NSF2_NOPLAY "NSF2 No PLAY routine"
LOCALPROP NSF2_MANDATORY "NSF2 Mandatory Metadata Flag"
LOCALPROP NSFE_PLAYLIST "Playlist Present"

LOCALGROUP DATA "Data" "Raw NSF file data"
LOCALPROP NSF_HEADER "NSF Header Raw Data"

LOCALGROUP ACTIVE "Active" "Active state properties"
Expand Down
98 changes: 53 additions & 45 deletions enums/nsfplayenums.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,21 @@
# SETLIST group-key key list-key default-key
# SETSTR group-key key "default"
#
# Properties can have an optional comment string in the generated enum.
# Properties can have an optional comment string after the generated enum.
# NSF Properties.
# PROPINT key display-type [comment]
# PROPLONG key display-type [comment]
# PROPSTR key [comment]
# PROPLINES key [comment]
# PROPBLOB key [comment]
# PROPLIST key list-key [comment]
# PROPINT key display-type "comment"
# PROPLONG key display-type "comment"
# PROPSTR key "comment"
# PROPLINES key "comment"
# PROPBLOB key "comment"
# PROPLIST key list-key "comment"
# Song Properties.
# SONGPROPINT key display-type [comment]
# SONGPROPLONG key display-type [comment]
# SONGPROPSTR key [comment]
# SONGPROPLINES key [comment]
# SONGPROPBLOB key [comment]
# SONGPROPLIST key list-key [comment]
# SONGPROPINT key display-type "comment"
# SONGPROPLONG key display-type "comment"
# SONGPROPSTR key "comment"
# SONGPROPLINES key "comment"
# SONGPROPBLOB key "comment"
# SONGPROPLIST key list-key "comment"
#
# Global channel info.
# The UNIT will also generate a settings group "UNIT", with a VOL setting.
Expand Down Expand Up @@ -276,26 +276,27 @@ def verbose(message):
PARSE_KEYS,
PARSE_GT,
PARSE_DT,
) = range(0,6)
PARSE_COM,
) = range(0,7)

PARSE_DEFS = {
"LIST":[PARSE_KEY,PARSE_KEYS],
"GROUP":[PARSE_GT,PARSE_KEY],
"SETINT":[PARSE_KEY,PARSE_KEY,PARSE_INT,PARSE_INT,PARSE_INT,PARSE_INT,PARSE_INT,PARSE_DT],
"SETLIST":[PARSE_KEY,PARSE_KEY,PARSE_KEY,PARSE_KEY],
"SETSTR":[PARSE_KEY,PARSE_KEY,PARSE_STR],
"PROPINT":[PARSE_KEY,PARSE_KEY,PARSE_DT],
"PROPLONG":[PARSE_KEY,PARSE_KEY,PARSE_DT],
"PROPSTR":[PARSE_KEY,PARSE_KEY],
"PROPLINES":[PARSE_KEY,PARSE_KEY],
"PROPBLOB":[PARSE_KEY,PARSE_KEY],
"PROPLIST":[PARSE_KEY,PARSE_KEY,PARSE_KEY],
"SONGPROPINT":[PARSE_KEY,PARSE_KEY,PARSE_DT],
"SONGPROPLONG":[PARSE_KEY,PARSE_KEY,PARSE_DT],
"SONGPROPSTR":[PARSE_KEY,PARSE_KEY],
"SONGPROPLINES":[PARSE_KEY,PARSE_KEY],
"SONGPROPBLOB":[PARSE_KEY,PARSE_KEY],
"SONGPROPLIST":[PARSE_KEY,PARSE_KEY,PARSE_KEY],
"PROPINT":[PARSE_KEY,PARSE_KEY,PARSE_DT,PARSE_COM],
"PROPLONG":[PARSE_KEY,PARSE_KEY,PARSE_DT,PARSE_COM],
"PROPSTR":[PARSE_KEY,PARSE_KEY,PARSE_COM],
"PROPLINES":[PARSE_KEY,PARSE_KEY,PARSE_COM],
"PROPBLOB":[PARSE_KEY,PARSE_KEY,PARSE_COM],
"PROPLIST":[PARSE_KEY,PARSE_KEY,PARSE_KEY,PARSE_COM],
"SONGPROPINT":[PARSE_KEY,PARSE_KEY,PARSE_DT,PARSE_COM],
"SONGPROPLONG":[PARSE_KEY,PARSE_KEY,PARSE_DT,PARSE_COM],
"SONGPROPSTR":[PARSE_KEY,PARSE_KEY,PARSE_COM],
"SONGPROPLINES":[PARSE_KEY,PARSE_KEY,PARSE_COM],
"SONGPROPBLOB":[PARSE_KEY,PARSE_KEY,PARSE_COM],
"SONGPROPLIST":[PARSE_KEY,PARSE_KEY,PARSE_KEY,PARSE_COM],
"UNIT":[PARSE_KEY],
"CHANNEL":[PARSE_KEY,PARSE_KEY,PARSE_INT],
"CHANNELUNSET":[PARSE_KEY,PARSE_KEY,PARSE_KEY],
Expand All @@ -321,6 +322,7 @@ def verbose(message):
PARSE_KEYS:"KEY...",
PARSE_DT:"DISPLAY",
PARSE_GT:"GROUP-TYPE",
PARSE_COM:"COMMENT",
}

#
Expand Down Expand Up @@ -363,8 +365,13 @@ def parse_entry(ls):
p = []
ls = ls[1:]
for pd in parse_def:
if len(ls) < 1:
parse_error(PARSE_DEF_NAME[pd]+" expected: (end of line)")
if pd == PARSE_COM: # optional comment
if (len(ls)>0):
p.append(ls[0])
else:
p.append(None)
elif len(ls) < 1:
parse_error(PARSE_DEF_NAME[pd]+" expected at end of line.")
return (None,None)
elif pd == PARSE_KEY:
if not is_key(ls[0]):
Expand Down Expand Up @@ -534,23 +541,23 @@ def parse_enums(path):
elif command == "SETSTR": # 0-group 1-key 2-default
add_set((p[1],p[0],p[2],0,0,0,0,None,True,DT_STR))
# PROP
elif command == "PROPINT": add_prop((p[1],p[0],PROP_INT,p[2],None)) # 0-key 1-group-key(index) 2-type 3-display 4-list-index
elif command == "PROPLONG": add_prop((p[1],p[0],PROP_LONG,p[2],None))
elif command == "PROPSTR": add_prop((p[1],p[0],PROP_STR,DT_STR,None))
elif command == "PROPLINES": add_prop((p[1],p[0],PROP_LINES,DT_LINES,None))
elif command == "PROPBLOB": add_prop((p[1],p[0],PROP_BLOB,DT_BLOB,None))
elif command == "PROPINT": add_prop((p[1],p[0],PROP_INT,p[2],None,p[3])) # 0-key 1-group-key(index) 2-type 3-display 4-list-index 5-commend
elif command == "PROPLONG": add_prop((p[1],p[0],PROP_LONG,p[2],None,p[3]))
elif command == "PROPSTR": add_prop((p[1],p[0],PROP_STR,DT_STR,None,p[2]))
elif command == "PROPLINES": add_prop((p[1],p[0],PROP_LINES,DT_LINES,None,p[2]))
elif command == "PROPBLOB": add_prop((p[1],p[0],PROP_BLOB,DT_BLOB,None,p[2]))
elif command == "PROPLIST":
(li,lk,dcount) = check_list(p[2])
if (li != None): add_prop((p[1],p[0],PROP_LIST,DT_LIST,li))
if (li != None): add_prop((p[1],p[0],PROP_LIST,DT_LIST,li,p[3]))
# SONGPROP
elif command == "SONGPROPINT": add_prop((p[1],p[0],PROP_INT,p[2],None),True)
elif command == "SONGPROPLONG": add_prop((p[1],p[0],PROP_LONG,p[2],None),True)
elif command == "SONGPROPSTR": add_prop((p[1],p[0],PROP_STR,DT_STR,None),True)
elif command == "SONGPROPLINES": add_prop((p[1],p[0],PROP_LINES,DT_LINES,None),True)
elif command == "SONGPROPBLOB": add_prop((p[1],p[0],PROP_BLOB,DT_BLOB,None),True)
elif command == "SONGPROPINT": add_prop((p[1],p[0],PROP_INT,p[2],None,p[3]),True)
elif command == "SONGPROPLONG": add_prop((p[1],p[0],PROP_LONG,p[2],None,p[3]),True)
elif command == "SONGPROPSTR": add_prop((p[1],p[0],PROP_STR,DT_STR,None,p[2]),True)
elif command == "SONGPROPLINES": add_prop((p[1],p[0],PROP_LINES,DT_LINES,None,p[2]),True)
elif command == "SONGPROPBLOB": add_prop((p[1],p[0],PROP_BLOB,DT_BLOB,None,p[2]),True)
elif command == "SONGPROPLIST":
(li,lk,dcount) = check_list(p[2])
if (li != None): add_prop((p[1],p[0],PROP_LIST,DT_LIST,li),True)
if (li != None): add_prop((p[1],p[0],PROP_LIST,DT_LIST,li,p[3]),True)
elif command == "UNIT":
add_unique_entry(defs_unit,1,"UNIT "+p[0],p)
add_unique_entry(defs_group,1,"GROUP(UNIT) "+p[0],(p[0],GT_SET))
Expand Down Expand Up @@ -679,9 +686,10 @@ def gen_line(l,target=0):
def gen_break(target=0):
gen_line("",target)

def gen_enum(key,value,target=0,hexadecimal=False):
if not hexadecimal: gen_line("const int32_t %-42s %12d;" % (key+" =",value),target)
else: gen_line("const int32_t %-42s %12X;" % (key+" =",value),target)
def gen_enum(key,value,comment=None,target=0,hexadecimal=False):
suffix = "" if (comment == None or len(comment) < 1) else " // "+comment
if not hexadecimal: gen_line("const int32_t %-42s %12d;%s" % (key+" =",value,suffix),target)
else: gen_line("const int32_t %-42s %12X;%s" % (key+" =",value,suffix),target)

def gen_text(text): # adds utf-8 string to text blob, returns offset to it, duplicates are reused
global gen_text_blob, gen_text_map
Expand Down Expand Up @@ -1018,7 +1026,7 @@ def generate_enums(file_enum,file_data,do_write):
gen_line("const NSFPropData NSFD_PROP[NSF_PROP_COUNT] = {",1)
for spi in range(len(sorted_props)):
pi = sorted_props[spi][1]
(prop_key,gi,prop_type,prop_display,prop_list) = defs_prop[pi]
(prop_key,gi,prop_type,prop_display,prop_list,prop_comment) = defs_prop[pi]
prop_group_type = defs_group[gi][1]
list_index = -1
list_max = 0
Expand All @@ -1029,7 +1037,7 @@ def generate_enums(file_enum,file_data,do_write):
'"'+prop_key+'"',
gi,len(table_locale[0]),prop_type,prop_display,
list_max,list_index),1)
gen_enum("NSF_PROP_"+prop_key,spi);
gen_enum("NSF_PROP_"+prop_key,spi,prop_comment);
names = [prop_key for i in range(locs)]
for i in range(locs):
name = None
Expand Down
15 changes: 10 additions & 5 deletions enums/settings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ SETINT TEST TEST_PRECISE 42 0 1000 0 1000 PRECISE

GROUP PROP NSF
PROPLIST NSF FILE_TYPE FILE_TYPE
PROPINT NSF NSF_SONG_COUNT INT
PROPINT NSF NSF_SONG_START INT
PROPINT NSF NSF_SONG_COUNT INT "NSF header data, use ACTIVE_SONG_COUNT with NSFPlay interface"
PROPINT NSF NSF_SONG_START INT "NSF header data, use ACTIVE_SONG_START with NSFPlay interface"
PROPINT NSF NSF_VERSION INT
PROPINT NSF LOAD_ADDR HEX16
PROPINT NSF INIT_ADDR HEX16
Expand Down Expand Up @@ -205,12 +205,17 @@ PROPINT NSF NSF2_INIT_NORETURN BOOL
PROPINT NSF NSF2_NOPLAY BOOL
PROPINT NSF NSF2_MANDATORY BOOL
PROPBLOB NSF NSFE_PLAYLIST

GROUP PROP DATA
PROPBLOB NSF NSF_HEADER
# TODO all known NSFe blobs

GROUP PROP ACTIVE
PROPINT ACTIVE ACTIVE_SONG_COUNT INT
PROPINT ACTIVE ACTIVE_SONG_START INT
PROPINT ACTIVE ACTIVE_PLAYLIST BOOL
PROPINT ACTIVE ACTIVE_SONG INT "Current song for NSFPlay interface (includes PLAYLIST override)"
PROPINT ACTIVE ACTIVE_SONG_COUNT INT "Song count for NSFPlay interface (includes PLAYLIST override)"
PROPINT ACTIVE ACTIVE_SONG_START INT "Song start for NSFPlay interface (includes PLAYLIST override)"
PROPINT ACTIVE ACTIVE_PLAYLIST BOOL "Indicates whether a playlist is overriding the NSF song list"
PROPINT ACTIVE ACTIVE_SONG_NSF INT "Current song in the NSF song list, use ACTIVE_SONG with NSFPlay interface"

# TODO blobs for other NSFe properties?
# TODO song properties, how many of these have NSFe properties too?
Expand Down
5 changes: 3 additions & 2 deletions include/nsfplaycore.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,14 @@ bool nsfplay_load(NSFCore* core, const void* nsf_data, uint32_t nsf_size, bool a
bool nsfplay_load_bin(NSFCore* core, const void* bin_data, uint32_t bin_size, bool assume);

// song control
uint32_t nsfplay_song_count(const NSFCore* core); // number of songs in loaded NSF
uint32_t nsfplay_song_count(const NSFCore* core); // number of songs in loaded NSF (or NSF playlist if active, see PROP_ACTIVE_PLAYLIST)
uint32_t nsfplay_song_current(const NSFCore* core); // current active song
bool nsfplay_song(NSFCore* core, uint8_t song); // set song, false if song out of bounds, automatically calls song_play
void nsfplay_song_play(NSFCore* core); // resets the song and executes its INIT routine
void nsfplay_seek(NSFCore* core, uint64_t samples);
uint64_t nsfplay_samples_played(const NSFCore* core); // samples since song_play

// advance emulation and render sound samples
// emulate and render sound samples
// - every two elements of stereo_output alternates left channel, right channel (length must be 2*samples)
// - stereo_output can be NULL if the output isn't needed
// - returns number of samples rendered, may be less than samples if song is finished (will zero fill unused output samples)
Expand Down
Loading

0 comments on commit 2e6e1c1

Please sign in to comment.