Strip old c and c++ stuff
This commit is contained in:
parent
0a4484578b
commit
77c2371eff
@ -1,9 +0,0 @@
|
||||
.PHONY: all base cli clean
|
||||
all: base cli
|
||||
base:
|
||||
$(MAKE) -C base
|
||||
cli:
|
||||
$(MAKE) -C cli
|
||||
clean:
|
||||
$(MAKE) -C base clean
|
||||
$(MAKE) -C cli clean
|
@ -1,10 +0,0 @@
|
||||
CXXFLAGS = -g
|
||||
OBJS = cyoa.o storybook.o
|
||||
|
||||
all: libstorybook.a
|
||||
libstorybook.a: $(OBJS)
|
||||
ar rcs $@ $^
|
||||
cyoa.cpp: cyoa.leg
|
||||
leg -o $@ $^
|
||||
clean:
|
||||
rm -f cyoa.c $(OBJS)
|
@ -1,67 +0,0 @@
|
||||
#ifndef CYOA_H
|
||||
#define CYOA_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#define STATCHECK_GT 1
|
||||
#define STATCHECK_LT 2
|
||||
|
||||
namespace storybook {
|
||||
struct statcheck_t {
|
||||
char *stat;
|
||||
int value;
|
||||
int rel;
|
||||
};
|
||||
|
||||
struct statchange_t {
|
||||
char *stat;
|
||||
int addend;
|
||||
};
|
||||
|
||||
struct Choice {
|
||||
int option;
|
||||
char *flavor;
|
||||
statcheck_t *statcheck;
|
||||
char *id;
|
||||
statchange_t *statchange;
|
||||
|
||||
Choice(int);
|
||||
};
|
||||
|
||||
typedef std::map<int, Choice*> ChoiceList;
|
||||
|
||||
enum class FooterType {
|
||||
End,
|
||||
Goto,
|
||||
Choices
|
||||
};
|
||||
|
||||
struct Footer {
|
||||
FooterType type;
|
||||
union {
|
||||
ChoiceList *choices;
|
||||
char *link;
|
||||
};
|
||||
|
||||
Footer();
|
||||
~Footer();
|
||||
};
|
||||
|
||||
struct Page {
|
||||
char *id;
|
||||
char *body;
|
||||
Footer footer;
|
||||
|
||||
Page();
|
||||
~Page();
|
||||
};
|
||||
|
||||
std::vector<Page*> CyoaParse(FILE *);
|
||||
}
|
||||
|
||||
#endif /* CYOA_H */
|
||||
|
||||
// Local Variables:
|
||||
// mode: c++
|
||||
// End:
|
@ -1,167 +0,0 @@
|
||||
%{
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include "cyoa.h"
|
||||
|
||||
using namespace storybook;
|
||||
|
||||
FILE* yyin = stdin;
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) { \
|
||||
int yyc = getc(yyin); \
|
||||
result = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); \
|
||||
}
|
||||
|
||||
std::vector<Page*> pages;
|
||||
|
||||
Page *emit_ending();
|
||||
Page *emit_goto(char*);
|
||||
Page *emit_choices(ChoiceList*);
|
||||
|
||||
void append_body(Page *page, char *str);
|
||||
|
||||
union value {
|
||||
Page *page;
|
||||
char *string;
|
||||
Choice *choice;
|
||||
ChoiceList *choices;
|
||||
int num;
|
||||
statcheck_t *statcheck;
|
||||
statchange_t *statchange;
|
||||
};
|
||||
|
||||
#define YYSTYPE union value
|
||||
|
||||
%}
|
||||
|
||||
|
||||
Story = BlankLine* (p:Page { pages.push_back(p.page); })+ EndOfFile
|
||||
|
||||
Page = h:Header b:Body { $$.page = b.page; $$.page->id = h.string}
|
||||
BlankLine*
|
||||
|
||||
Header = < i:Identifier > Newline BlankLine* { $$ = i; }
|
||||
|
||||
Identifier = < [A-Z][A-Z0-9_]+ > - { $$.string = strndup(yytext, yyleng); }
|
||||
|
||||
Body = Footer | t:TextLine b:Body { $$ = b; append_body(b.page, t.string);}
|
||||
|
||||
TextLine = < (!Newline .)* Newline > { $$.string = strndup(yytext, yyleng); }
|
||||
|
||||
Footer = Ending { $$.page = emit_ending(); }
|
||||
| g:Goto { $$.page = emit_goto(g.string); }
|
||||
| c:ChoiceList { $$.page = emit_choices(c.choices); }
|
||||
|
||||
Goto = 'GOTO' - < i:Identifier > Newline
|
||||
{ $$.string = strndup(yytext, yyleng); }
|
||||
|
||||
Ending = 'THE END' Newline
|
||||
|
||||
ChoiceList = c:Choice l:ChoiceList { $$ = l; (*$$.choices)[c.choice->option] = c.choice; }
|
||||
| c:Choice { $$.choices = new ChoiceList(); (*$$.choices)[c.choice->option] = c.choice; }
|
||||
|
||||
Choice = b:Bullet
|
||||
f:Freetext { b.choice->flavor = f.string; }
|
||||
(ck:StatCheck { b.choice->statcheck = ck.statcheck; })?
|
||||
'[' i:Identifier ']' { b.choice->id = i.string; } -
|
||||
(cg:StatChange { b.choice->statchange = cg.statchange; })?
|
||||
Newline { $$ = b; }
|
||||
;
|
||||
|
||||
Bullet = < [0-9]+ > ')' - { $$.choice = new Choice(atoi(yytext)); }
|
||||
|
||||
Freetext = < ([^[<])+ > { $$.string = strndup(yytext, yyleng); }
|
||||
|
||||
StatCheck = '<' n:StatName v:StatVal r:StatRel '>' -
|
||||
{ $$.statcheck = new statcheck_t{n.string, v.num, r.num}; }
|
||||
|
||||
StatChange = '(' ('+' | '-') v:StatVal n:StatName ')'
|
||||
{ $$.statchange = new statchange_t{n.string, v.num}; }
|
||||
|
||||
StatName = < [A-Za-z]+ > - { $$.string = strdup(yytext); }
|
||||
|
||||
StatVal = < [0-9]+ > - { $$.num = atoi(yytext); }
|
||||
|
||||
StatRel = < ('+'|'-')? > { $$.num = yytext[0] == '+' ? STATCHECK_GT : STATCHECK_LT; } -
|
||||
|
||||
EndOfFile = !.
|
||||
|
||||
BlankLine = - Newline
|
||||
|
||||
- = (' ' | '\t')*
|
||||
|
||||
Newline = '\r\n' | '\r' | '\n'
|
||||
|
||||
%%
|
||||
|
||||
Choice::Choice(int option) {
|
||||
this->option = option;
|
||||
this->statcheck = NULL;
|
||||
this->statchange = NULL;
|
||||
}
|
||||
|
||||
Footer::Footer() {
|
||||
}
|
||||
|
||||
Footer::~Footer() {
|
||||
}
|
||||
|
||||
Page::Page() {
|
||||
id = NULL;
|
||||
body = NULL;
|
||||
}
|
||||
|
||||
Page::~Page() {
|
||||
if (id) {
|
||||
free(id);
|
||||
}
|
||||
if (body) {
|
||||
free(body);
|
||||
}
|
||||
}
|
||||
|
||||
Page *emit_goto(char *id) {
|
||||
Page *mypage = new Page;
|
||||
mypage->footer.type = FooterType::Goto;
|
||||
mypage->footer.link = id;
|
||||
return mypage;
|
||||
}
|
||||
|
||||
Page *emit_ending() {
|
||||
Page *mypage = new Page;
|
||||
mypage->footer.type = FooterType::End;
|
||||
return mypage;
|
||||
}
|
||||
|
||||
Page *emit_choices(ChoiceList *choices) {
|
||||
Page *mypage = new Page;
|
||||
mypage->footer.type = FooterType::Choices;
|
||||
mypage->footer.choices = choices;
|
||||
return mypage;
|
||||
}
|
||||
|
||||
void append_body(Page *page, char *str) {
|
||||
if (page->body) {
|
||||
int size = strlen(page->body) + strlen(str) + 1;
|
||||
char *newstring = (char*) calloc(size, sizeof(char));
|
||||
strcpy(newstring, str);
|
||||
strcat(newstring, page->body);
|
||||
free(page->body);
|
||||
page->body = newstring;
|
||||
} else {
|
||||
page->body = str;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Page*> storybook::CyoaParse(FILE *file) {
|
||||
yyin = file;
|
||||
yyparse();
|
||||
yyin = stdin;
|
||||
return pages;
|
||||
}
|
||||
|
||||
/* Local Variables: */
|
||||
/* mode: text */
|
||||
/* End: */
|
@ -1,139 +0,0 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "storybook.h"
|
||||
|
||||
using namespace storybook;
|
||||
|
||||
Storybook::Storybook() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
Storybook::Storybook(FILE* fin) {
|
||||
pages = CyoaParse(fin);
|
||||
}
|
||||
|
||||
void Storybook::UpdateStat(const char *ckey, int rel) {
|
||||
std::string key(ckey);
|
||||
auto it = stats.find(key);
|
||||
if (it == stats.end()) {
|
||||
// Key not present
|
||||
stats[key] = rel;
|
||||
} else {
|
||||
// Key present, add the rel
|
||||
stats[key] = it->second + rel;
|
||||
}
|
||||
}
|
||||
|
||||
int Storybook::LookupStat(const char *ckey) {
|
||||
std::string key(ckey);
|
||||
auto it = stats.find(key);
|
||||
if (it == stats.end()){
|
||||
stats[key] = 0;
|
||||
return 0;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Storybook::Find(const char *id) {
|
||||
for (Page* page : pages) {
|
||||
if (strcmp(page->id, id) == 0) {
|
||||
current = page;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If not found
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
void Storybook::Advance() {
|
||||
// TODO throw an exception if the ending type is choices
|
||||
switch(current->footer.type) {
|
||||
case FooterType::End:
|
||||
IsEnded = true;
|
||||
current = NULL;
|
||||
return;
|
||||
case FooterType::Goto:
|
||||
Find(current->footer.link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Storybook::Advance(int choice_option) {
|
||||
if (!IsChoiceAvailable(choice_option)) {
|
||||
throw IllegalChoiceException();
|
||||
}
|
||||
|
||||
Choice* choice = (*current->footer.choices)[choice_option];
|
||||
|
||||
if (statchange_t *cg = choice->statchange)
|
||||
UpdateStat(cg->stat, cg->addend);
|
||||
|
||||
Find(choice->id);
|
||||
}
|
||||
|
||||
bool Storybook::IsChoiceAvailable(int choice_option) {
|
||||
Choice* choice = (*current->footer.choices)[choice_option];
|
||||
if (!choice)
|
||||
return false;
|
||||
|
||||
statcheck_t *ck = choice->statcheck;
|
||||
if (ck) {
|
||||
int val = LookupStat(ck->stat);
|
||||
if (ck->rel == STATCHECK_GT && val < ck->value ||
|
||||
ck->rel == STATCHECK_LT && val > ck->value)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Storybook::print_choice(Choice* c) {
|
||||
if (!IsChoiceAvailable(c->option))
|
||||
printf("\033[;31m"); // Red background
|
||||
|
||||
printf("%d) %s", c->option, c->flavor);
|
||||
if (c->statchange) {
|
||||
printf("(%s %+d)",
|
||||
c->statchange->stat,
|
||||
c->statchange->addend);
|
||||
}
|
||||
if (!IsChoiceAvailable(c->option))
|
||||
printf("\033[;0m");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void Storybook::Play() {
|
||||
printf(current->body);
|
||||
Choice *choice;
|
||||
|
||||
switch (current->footer.type) {
|
||||
case FooterType::End:
|
||||
printf("The End.");
|
||||
Advance();
|
||||
break;
|
||||
case FooterType::Goto:
|
||||
Advance();
|
||||
printf("Press ENTER to continue...");
|
||||
std::cin.get();
|
||||
break;
|
||||
case FooterType::Choices:
|
||||
for (auto c : *current->footer.choices) {
|
||||
print_choice(c.second);
|
||||
}
|
||||
printf("Make a selection: ");
|
||||
int choice_option;
|
||||
std::cin >> choice_option;
|
||||
try {
|
||||
Advance(choice_option);
|
||||
} catch (IllegalChoiceException e) {
|
||||
printf("You can't do that!\n\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
IsEnded = true;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
#ifndef STORYBOOK_H
|
||||
#define STORYBOOK_H
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include "cyoa.h"
|
||||
|
||||
namespace storybook {
|
||||
|
||||
class Storybook {
|
||||
private:
|
||||
std::vector<Page*> pages;
|
||||
std::unordered_map<std::string, int> stats;
|
||||
Page *current;
|
||||
|
||||
void print_choice(Choice *c);
|
||||
public:
|
||||
Storybook();
|
||||
Storybook(FILE* fin);
|
||||
|
||||
// Functions for looking up and printing stats
|
||||
void UpdateStat(const char*, int);
|
||||
int LookupStat(const char*);
|
||||
std::vector<std::string> GetDefinedStats();
|
||||
|
||||
// Functions to change the game state
|
||||
void Find(const char*);
|
||||
void Advance(); // For Goto and End cases
|
||||
void Advance(int); // For Choices
|
||||
bool IsChoiceAvailable(int);
|
||||
bool IsEnded = false;
|
||||
|
||||
// This will probably be moved to the cli driver
|
||||
void Play();
|
||||
|
||||
class IllegalChoiceException : std::exception {
|
||||
virtual const char *what() const noexcept {
|
||||
return "Illegal Choice.";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif /* STORYBOOK_H */
|
@ -1,5 +0,0 @@
|
||||
CXXFLAGS = -g -L../base/
|
||||
.PHONY: all clean
|
||||
all: storybook-cli
|
||||
storybook-cli: storybook_cli.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^ -lstorybook
|
@ -1,32 +0,0 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "../base/storybook.h"
|
||||
|
||||
void usage(const char* bin) {
|
||||
fprintf(stderr, "Usage: %s <storyfile>", bin);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
if (argc != 2) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
FILE *fin = fopen(argv[1], "r");
|
||||
if (!fin) {
|
||||
fprintf(stderr, "Error: could not read %s", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
storybook::Storybook sb(fin);
|
||||
fclose(fin);
|
||||
|
||||
sb.Find("START");
|
||||
sb.Play();
|
||||
|
||||
while (!sb.IsEnded) {
|
||||
sb.Play();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
7
src/godot/.gitignore
vendored
7
src/godot/.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
.sconsign.dblite
|
||||
bin/
|
||||
*.os
|
||||
*.so
|
||||
*.o
|
||||
logs/
|
||||
storybook.h
|
@ -1,10 +0,0 @@
|
||||
LDFLAGS := -Wl,--gc-sections -lpthread -ldl -rdynamic -shared
|
||||
CFLAGS := -g -std=c11 -fPIC -Igodot-headers
|
||||
|
||||
.PHONY: all
|
||||
all: libstorybook.so
|
||||
libstorybook.so: storybook.o ../rust-base/target/debug/libstorybook.a
|
||||
$(CC) $(LDFLAGS) $^ -o $@
|
||||
storybook.o: storybook.h
|
||||
storybook.h:
|
||||
cbindgen -c ../rust-base/cbindgen.toml --crate storybook --lang c -o $@ ../rust-base
|
@ -1 +0,0 @@
|
||||
Subproject commit bd863357de5b1fa8e04ebffbbb30d28425de9723
|
@ -1,127 +0,0 @@
|
||||
#include <gdnative_api_struct.gen.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "storybook.h"
|
||||
|
||||
const godot_gdnative_core_api_struct *api = NULL;
|
||||
const godot_gdnative_ext_nativescript_api_struct *nativescript_api = NULL;
|
||||
|
||||
void *storybook_godot_constructor(godot_object *p_instance, void *p_method_data);
|
||||
void storybook_godot_destructor(godot_object *p_instance, void *p_method_data, void *p_user_data);
|
||||
godot_variant storybook_godot_parse(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args);
|
||||
godot_variant storybook_godot_get_body(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args);
|
||||
godot_variant storybook_godot_advance(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args);
|
||||
godot_variant storybook_godot_get_footer(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args);
|
||||
|
||||
void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *p_options) {
|
||||
api = p_options->api_struct;
|
||||
|
||||
for (int i = 0; i < api->num_extensions; i++) {
|
||||
switch(api->extensions[i]->type) {
|
||||
case GDNATIVE_EXT_NATIVESCRIPT: {
|
||||
nativescript_api = (godot_gdnative_ext_nativescript_api_struct *)api->extensions[i];
|
||||
}; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *p_options) {
|
||||
api = NULL;
|
||||
nativescript_api = NULL;
|
||||
}
|
||||
|
||||
#define register_method(meth) \
|
||||
godot_instance_method meth = { NULL, NULL, NULL}; \
|
||||
meth.method = &storybook_godot_ ## meth; \
|
||||
nativescript_api->godot_nativescript_register_method(p_handle, "STORYBOOK", #meth, attributes, meth)
|
||||
|
||||
void GDN_EXPORT godot_nativescript_init(void *p_handle) {
|
||||
godot_instance_create_func create = { NULL, NULL, NULL };
|
||||
create.create_func = &storybook_godot_constructor;
|
||||
|
||||
godot_instance_destroy_func destroy = { NULL, NULL, NULL };
|
||||
destroy.destroy_func = &storybook_godot_destructor;
|
||||
|
||||
nativescript_api->godot_nativescript_register_class(p_handle, "STORYBOOK", "Reference",
|
||||
create, destroy);
|
||||
|
||||
godot_method_attributes attributes = { GODOT_METHOD_RPC_MODE_DISABLED };
|
||||
|
||||
register_method(parse);
|
||||
register_method(get_body);
|
||||
register_method(advance);
|
||||
register_method(get_footer);
|
||||
}
|
||||
|
||||
typedef struct user_data_struct {
|
||||
Book *book;
|
||||
} user_data_struct;
|
||||
|
||||
void *storybook_godot_constructor(godot_object *p_instance, void *p_method_data){
|
||||
user_data_struct *user_data = api->godot_alloc(sizeof(user_data_struct));
|
||||
return user_data;
|
||||
}
|
||||
|
||||
void storybook_godot_destructor(godot_object *p_instance, void *p_method_data, void *p_user_data) {
|
||||
user_data_struct *user_data = (user_data_struct*) p_user_data;
|
||||
storybook_free_book(user_data->book);
|
||||
api->godot_free(user_data);
|
||||
}
|
||||
|
||||
godot_variant storybook_godot_parse(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) {
|
||||
godot_variant ret;
|
||||
godot_string str = api->godot_variant_as_string(p_args[0]);
|
||||
godot_char_string utf8 = api->godot_string_utf8(&str);
|
||||
|
||||
user_data_struct *user_data = (user_data_struct*) p_user_data;
|
||||
user_data->book = storybook_make_book(api->godot_char_string_get_data(&utf8));
|
||||
api->godot_char_string_destroy(&utf8);
|
||||
|
||||
api->godot_variant_new_nil(&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
godot_variant storybook_godot_get_body(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) {
|
||||
godot_variant ret;
|
||||
godot_string str;
|
||||
|
||||
user_data_struct *user_data = (user_data_struct*) p_user_data;
|
||||
char *body = storybook_get_body(user_data->book);
|
||||
api->godot_string_new(&str);
|
||||
api->godot_string_parse_utf8(&str, body);
|
||||
storybook_free_string(body);
|
||||
|
||||
api->godot_variant_new_string(&ret, &str);
|
||||
api->godot_string_destroy(&str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
godot_variant storybook_godot_advance(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) {
|
||||
godot_variant ret;
|
||||
|
||||
user_data_struct *user_data = (user_data_struct*) p_user_data;
|
||||
|
||||
if (p_num_args == 0) {
|
||||
storybook_advance_nooption(user_data->book);
|
||||
} else {
|
||||
uint64_t option = api->godot_variant_as_uint(p_args[0]);
|
||||
storybook_advance_option(user_data->book, option);
|
||||
}
|
||||
|
||||
api->godot_variant_new_nil(&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
godot_variant storybook_godot_get_footer(godot_object *p_instance, void *p_method_data, void *p_user_data, int p_num_args, godot_variant **p_args) {
|
||||
godot_variant ret;
|
||||
|
||||
user_data_struct *user_data = (user_data_struct*) p_user_data;
|
||||
footer ft = storybook_get_footer(user_data->book);
|
||||
|
||||
api->godot_variant_new_int(&ret, ft);
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue
Block a user