From 81381df227462533056d424b55fd4157e30ae973 Mon Sep 17 00:00:00 2001 From: GeneralGuy4872 Date: Mon, 28 Oct 2019 12:24:36 -0500 Subject: [PATCH] overhaul room system reap dead code make a roadmap to prealpha --- README.md | 25 +- depricated/abandoned.messy | 362 +++++++++++++++++ src/constants.h | 17 +- src/iwannaflycurses.messy | 592 +++++++++------------------- src/macro.h | 7 +- src/modules/IWannaFly/LinkedList.pm | 135 ++++--- src/modules/IWannaFly/Main.pm | 13 +- src/modules/MyUtils/Macro.pm | 7 +- src/modules/MyUtils/Null.pm | 21 +- 9 files changed, 697 insertions(+), 482 deletions(-) create mode 100644 depricated/abandoned.messy diff --git a/README.md b/README.md index d7ae5e8..dbddd20 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Iwannafly ========= -*roguelike game library written in C, Perl, and Guile, with extension interface useing minimal external propagating dependencies* +*roguelike game library written in C and Perl with extension interface useing minimal external propagating dependencies* Dependencies: @@ -32,6 +32,7 @@ Build Deps: - Command make - Perl module Module::Build - Perl module ExtUtils::MakeMaker +- Perl module Parse::Yapp Build Recommends: - Command uname @@ -71,27 +72,23 @@ Depends: - C library \ - C library "XSUB.h" - C library "INLINE.h" -- C library \ - Perl feature "switch" - Perl module boolean - Perl module Exporter -- Perl module optimize::int -- Perl module Test::Simple -- Perl module Test::Type - Perl module Scalar::Util - Perl module Hash::Util - Perl module FastGlob (maybe?) - Perl module goto::file +- Perl module Data::Dumper - Perl module JSON - Perl module Config::Tiny -- Perl module IO::Pipe (maybe?) -- Perl module IO::Pty (possibly?) - Perl module Filter::Simple +- Perl module Math::RPN - Perl module Tie::File - Perl module (XS|Dyna)Loader -- Perl module Inline 'C' -- Perl module POSIX::(ceil|floor) +- Perl module POSIX::(ceil|floor|strfdate) - Perl module Acme::don't (no-ops during testing) +- Perl module Acme::Comment Recommends: - Command xterm (UTF-8, Color) @@ -109,7 +106,7 @@ Doc Build Deps: - Command make - Command perl - Command cp -- Perl module Module::Build +- Perl module Module::Build Doc Recommends: - Command xdvi @@ -118,6 +115,14 @@ Doc Recommends: NEWS (and Olds) --------------- +As of 28/10/2019, major changes to some of the oldest portions of the +outline are underway. these changes need to be propogated through the +entire project, and will result in major inconsistancies until finished. +once they are, work will begin twords the renderer, then a shakedown test +program for the camera, movement, and srolling. once the shakedown test +program begins the debug-compile-debug phase, dev state will be advanced +to Prealpha proper. + During Alpha, the project will be optemized for Devuan Linux, however, there are (theoretically) no distro-dependent elements, and the code should run on ANY *nix with properly fufilled dependancies by configuring paths.h diff --git a/depricated/abandoned.messy b/depricated/abandoned.messy new file mode 100644 index 0000000..d3f5010 --- /dev/null +++ b/depricated/abandoned.messy @@ -0,0 +1,362 @@ +/* buffered room loading for future implementation: + * roomtyp* ROOMARRAY[3][3][3] + * #define ROOM ROOMARRAY[1][1][1] + * #define ROOM_NORTH ROOMARRAY[1][0][1] + * #define ROOM_NE ROOMARRAY[1][0][2]) + * #define ROOM_EAST ROOMARRAY[1][1][2] + * #define ROOM_SE ROOMARRAY[1][2][2] + * #define ROOM_SOUTH ROOMARRAY[1][2][1] + * #define ROOM_SW ROOMARRAY[1][2][0] + * #define ROOM_WEST ROOMARRAY[1][1][0] + * #define ROOM_NW ROOMARRAY[1][0][0] + * #define ROOM_UP ROOMARRAY[0][1][1] + * #define ROOM_UP_NORTH ROOMARRAY[0][0][1] + * #define ROOM_UP_NE ROOMARRAY[0][0][2] + * #define ROOM_UP_EAST ROOMARRAY[0][1][2] + * #define ROOM_UP_SE ROOMARRAY[0][2][2] + * #define ROOM_UP_SOUTH ROOMARRAY[0][2][1] + * #define ROOM_UP_SW ROOMARRAY[0][2][0] + * #define ROOM_UP_WEST ROOMARRAY[0][1][0] + * #define ROOM_UP_NW ROOMARRAY[0][0][0] + * #define ROOM_DOWN ROOMARRAY[2][1][1] + * #define ROOM_DOWN_NORTH ROOMARRAY[2][0][1] + * #define ROOM_DOWN_NE ROOMARRAY[2][0][2] + * #define ROOM_DOWN_EAST ROOMARRAY[2][1][2] + * #define ROOM_DOWN_SE ROOMARRAY[2][2][2] + * #define ROOM_DOWN_SOUTH ROOMARRAY[2][2][1] + * #define ROOM_DOWN_SW ROOMARRAY[2][2][0] + * #define ROOM_DOWN_WEST ROOMARRAY[2][1][0] + * #define ROOM_DOWN_NW ROOMARRAY[2][0][0] + * + * masks to select rooms + * #define UP_ROOMS_MASK ((umint) 0xFF400000) + * #define DOWN_ROOMS_MASK ((umint) 0x000002FF) + * #define NORTH_ROOMS_MASK ((umint) 0xC10C10C1) + * #define SOUTH_ROOMS_MASK ((umint) 0x1C01C01C) + * #define EAST_ROOMS_MASK ((umint) 0x70070070) + * #define WEST_ROOMS_MASK ((umint) 0x07007007) + * #define ALL_ROOMS_MASK ((umint) 0xFF4FF2FF) + * + * #define ROOM_NORTH_MASKBIT ((umint) 0x00080000) + * #define ROOM_NE_MASKBIT ((umint) 0x00040000) + * #define ROOM_EAST_MASKBIT ((umint) 0x00020000) + * #define ROOM_SE_MASKBIT ((umint) 0x00010000) + * #define ROOM_SOUTH_MASKBIT ((umint) 0x00008000) + * #define ROOM_SW_MASKBIT ((umint) 0x00004000) + * #define ROOM_WEST_MASKBIT ((umint) 0x00002000) + * #define ROOM_NW_MASKBIT ((umint) 0x00001000) + * #define ROOM_UP_MASKBIT ((umint) 0x00400000) + * #define ROOM_UP_NORTH_MASKBIT ((umint) 0x80000000) + * #define ROOM_UP_NE_MASKBIT ((umint) 0x40000000) + * #define ROOM_UP_EAST_MASKBIT ((umint) 0x20000000) + * #define ROOM_UP_SE_MASKBIT ((umint) 0x10000000) + * #define ROOM_UP_SOUTH_MASKBIT ((umint) 0x08000000) + * #define ROOM_UP_SW_MASKBIT ((umint) 0x04000000) + * #define ROOM_UP_WEST_MASKBIT ((umint) 0x02000000) + * #define ROOM_UP_NW_MASKBIT ((umint) 0x01000000) + * #define ROOM_DOWN_MASKBIT ((umint) 0x00000200) + * #define ROOM_DOWN_NORTH_MASKBIT ((umint) 0x00000080) + * #define ROOM_DOWN_NE_MASKBIT ((umint) 0x00000040) + * #define ROOM_DOWN_EAST_MASKBIT ((umint) 0x00000020) + * #define ROOM_DOWN_SE_MASKBIT ((umint) 0x00000010) + * #define ROOM_DOWN_SOUTH_MASKBIT ((umint) 0x00000008) + * #define ROOM_DOWN_SW_MASKBIT ((umint) 0x00000004) + * #define ROOM_DOWN_WEST_MASKBIT ((umint) 0x00000002) + * #define ROOM_DOWN_NW_MASKBIT ((umint) 0x00000001) + */ + +getlinebuffer (y,x) +uchar y x +{ +char* LINEBUFFER = calloc(BUFFER_MAX,sizeof(char)) +move(y,x) +int ch +forever { + ch = getch(); + if ((ch > UCHAR_MAX) || (ch < 0)) { + switch ch : { + case KEY_ENTER : move(y,x); fputc('\n',LINEBUFFER); rewind(LINEBUFFER); return 0; + case KEY_BACKSPACE : move(y,x); rewind(LINEBUFFER); return 4; + case KEY_HOME : move(y,x); rewind(LINEBUFFER); break; + case KEY_LEFT : move(y,x); rewind(LINEBUFFER); break; + case KEY_SLEFT : move(y,x); rewind(LINEBUFFER); break; + default : break; + } break; + } + else if (ch < ' ') { + switch ch : { + case 0x17 : move(y,x); rewind(LINEBUFFER); return 4; + case '\n' : move(y,x); fputc('\n',LINEBUFFER); rewind(LINEBUFFER); return 0; + case '\b' : move(y,x); rewind(LINEBUFFER); return 4; + default: break; + } + } + else { + fputc(ch,LINEBUFFER); + printw(ch); + } + } +free(LINEBUFFER) +} + +umint getsixteen (y,x) +uchar y x +{ +char hexbuffer[8] = "00000000" +move(y,x-5);printw("[ - ]"); +int ch +uchar subscript = 0 +schar offset = subscript < 4 ? subscript-4 : subscript-3 +bool exiterr +forever { + ch = getch(); + if ((ch > UCHAR_MAX) || (ch < 0)) { + switch ch : { + case KEY_ENTER : goto(fin); + case KEY_BACKSPACE : subscript = INTVL(0,subscript-1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; + case KEY_LEFT : subscript = INTVL(0,subscript-1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; + case KEY_RIGHT : subscript = INTVL(0,subscript+1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; + case KEY_HOME : subscript = 0; offset = subscript < 4 ? subscript-4 : subscript-3; break; + case KEY_SLEFT : subscript = 0; offset = subscript < 4 ? subscript-4 : subscript-3; break; + case KEY_HOME : subscript = 7; offset = subscript < 4 ? subscript-4 : subscript-3; break; + case KEY_SRIGHT : subscript = 7; offset = subscript < 4 ? subscript-4 : subscript-3; break; + default : break; + } break; + } + else { + switch ch : { + case '\n' : goto(fin); + case '\b' : subscript = INTVL(0,subscript-1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; + case ' ' : subscript = INTVL(0,subscript+1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; + default: if (isxdigit(ch)) {hexbuffer[subscript] = ch; printw(ch);}; subscript = INTVL(0,subscript+1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; + } + } + move(y,x+offset); + } +fin: +return (umint) strtoul(hexbuffer,NULL,16); +} + +/*rotten pseudocode*/mapwarp(destination,tocoord) +latlontyp destination +coord3 tocoord +{ +saveroom() + +WORLD = destination + +mapscroll(NOSCROLL) + +loadroom(WORLD) + +if ((tocoord.x > MAX_X) || (tocoord.y > MAX_Y) || (tocoord.z ≥ CEILING)) { + PLAYER.pos.x = ROOM.home.x + PLAYER.pos.y = ROOM.home.y + PLAYER.pos.z = ROOM.home.z + } +else { + PLAYER.pos.x = tocoord.x + PLAYER.pos.y = tocoord.y + PLAYER.pos.z = tocoord.z + } +} + +/* typedef struct Rune { + * umint sym : 24; + * bool bold : 1; + * bool italic : 1; + * bool under : 1; + * bool strike : 1; + * bool over : 1; + * bool reverse : 1; + * bool blink : 1; + * bool invis : 1; + * } Rune; //not needed + */ + +struct mapscrollargs { +schar latmove : 2 +schar lonmove : 2 +schar depmove : 2 +bool stair : 1 +bool home : 1 +} + +mapscrollargs NOSCROLL = {0,0,0,false,false} + +/*implicit*/mapscroll(args) +mapscrollargs args +{ +BREAKCURSES +if (IS_XTERM) {printf("\033]2;IWannaFlyCurses - %s: loading...\033\\",GAMENAME);} +printf("loading..."); +fflush(stdout); +FIXCURSES +saveroom(NULL) +freeroom(NULL) +WORLD.coord.lat += args.latmove +if (WORLD.coord.lat > EQUATOR/4) { + WORLD.coord.lat = EQUATOR/2 - WORLD.coord.lat + WORLD.coord.lon += EQUATOR/2 + if (WORLD.coord.lon > EQUATOR/2) { + WORLD.coord.lon += -EQUATOR + } + } +else if (WORLD.coord.lat < -EQUATOR/4) { + WORLD.coord.lat = -EQUATOR/2 - WORLD.coord.lat + WORLD.coord.lon += EQUATOR/2 + if (WORLD.coord.lon > EQUATOR/2) { + WORLD.coord.lon += -EQUATOR + } + } + +WORLD.coord.lon += args.lonmove +if (WORLD.coord.lon ≥ EQUATOR/2) { + WORLD.coord.lon += -EQUATOR + } +else if (WORLD.coord.lon < -EQUATOR/2) { + WORLD.coord.lon += EQUATOR + } + +if ((args.depmove < 0) && (WORLD.coord.dep = 0)) { + depmove = 1 + WORLD.coord.lat = -WORLD.coord.lat + if (WORLD.coord.lon == -EQUATOR/2) {WORLD.coord.lon = 0} + else {WORLD.coord.lon = -WORLD.coord.lon} + } +else if ((args.depmove > 0) && (WORLD.coord.dep = ROOF)) { + /* death message (one of the following): + * flew too close to the sun + * was smited for rising too high + * grew too proud + * passed out in space and burned up on reentry + * froze to death in outer space + * became lost...in...spaaace! + */ + } +WORLD.coord.dep += args.depmove +if (depmove ≥ 0) : { + if (home) { + PLAYER.pos.x = ROOM.home.x + PLAYER.pos.y = ROOM.home.y + else if (stair) { + PLAYER.pos.x = ROOM.downstair.x + PLAYER.pos.y = ROOM.downstair.y + } + PLAYER.pos.z = 0 + } +else { + if (home) { + PLAYER.pos.x = ROOM.home.x + PLAYER.pos.y = ROOM.home.y + else if (stair) { + PLAYER.pos.x = ROOM.upstair.x + PLAYER.pos.y = ROOM.upstair.y + } + PLAYER.pos.z = CEILING + } + +ROOM = loadroom(WORLD) + +NEW = true +FIRST = !(visited) +ROOM.visited = true + +BREAKCURSES +if (IS_XTERM) {printf("\033]2;IWannaFlyCurses - %s: %i°%c, %i°%c, %i\033\\",GAMENAME,abs(WORLD.lat),WORLD.lat > 0 ? 'N' : (WORLD.lat < 0 ? 'S' : ' '),WORLD.lon > 0 ? 'E' : ((WORLD.lon < 0) && !(WORLD.lon == -180) ? 'W' : ' '),WORLD.dep - 100); +FIXCURSES +render(); +} + +/*ROTTEN pseudocode*/playermove(xmove,ymove,zmove) +schar xmove +schar ymove +schar zmove +{ +velocitycheck() +xymovecheck(xmove,ymove) +zmovecheck(zmove) + +PLAYER.pos.x += xmove +if (PLAYER.pos.x < 0) { + PLAYER.pos.x = mapscroll(-1,0).x + + } +else if (PLAYER.pos.x ≥ MAX_X) { + PLAYER.pos.x = mapscroll(1,0).x + } + +PLAYER.pos.y += ymove +if (PLAYER.pos.y < 0) { + PLAYER.pos.y = mapscroll(0,-1).y + } +else if (PLAYER.pos.y ≥ MAX_Y) { + PLAYER.pos.y = mapscroll(0,1).y + } + +PLAYER.pos.z += zmove +} + + +/* backslash enters console mode. characters are fetched and printed + * with ncurses, as well as stored in a temporary file. + * + * once the enter key is pressed, the temp file is rewound. + * a flex-generated parser is used to process the tokens. + * + * interpretation mode will change depending on the syntax. + * invalid commands may produce the response + * "Don't know how to ", amoungst others. + * + * a command will be provided to dump objects. + * text fields will show both their raw value and their text + * value in the correct encoding. using this comand to get + * out-of-character information is cheating, but no penalty + * can be implemented, as it would effect it's functionality. + * + * The internal debugger may produce intentional segfaults, + * which indicate a garbage pointer was dereferenced + * these should be called "dead canaries" in bugreports. + * these are useful in tracking down the most illusive of + * heisenbugs, as even if they cannot be directly observed, + * their modus operandi can be determined. + * + * only a number of expected variables may be dumped this way; + * true debugging should use GDB, perl -d, and possibly hexdump. + */ + +enum cli_argstypes +/* used to specify the type of the buffer that tokens are + * parsed into. types can be: + * + * argstype_wish (*heldobjtyp) (*heldobjtyp)[2] (*heldobjtyp)[4] + * argstyp_ent symtabref argstyp_equip equipenum + * + * container types will also allocate suitable contents + * once objid has been resolved + */ + +typedef cli_func *int(*void) + +enum commandenum +cli_func commandtable[256] +cli_argstypes commandargs[256] + +struct argstyp_wish { +uchar stack +objid type +void* data +} + +struct argstyp_ent { +bool shift +uchar race +bool stoned +} + +struct argstyp_equip { +equipenum slot +heldobjtyp* item +} + + diff --git a/src/constants.h b/src/constants.h index 9ceffb0..9d9e975 100644 --- a/src/constants.h +++ b/src/constants.h @@ -12,8 +12,6 @@ #define MAX_X 64 #define MAX_Y 24 //MAX_X ≥ MAX_Y ≥ MAX_Z #define MAX_Z 16 -#define CEILING ROOM->ceiling -#define ROOF 201 //it is decreed: mortals shall fly no higher. (this means you!) #define EQUATOR 360 //the number of rooms in the circumfrence of the sphere #define GOOD_MASK 0700 @@ -61,3 +59,18 @@ #define LIGHT_BIT 04 #define DARK_BIT 02 #define ENTROPY_BIT 01 + +#define GOLDMAX 130999 +#define COPPERMAX 99 + +#define ROOM_STACK_MAX 40 + +#define ROOM_UP 02 +#define ROOM_DOWN 03 +#define ROOM_NORTH 04 +#define ROOM_SOUTH 05 +#define ROOM_EAST 06 +#define ROOM_WEST 07 +#define ROOM_UPSTAIR 012 +#define ROOM_DOWNSTAIR 013 +#define ROOM_MIRROR 01 diff --git a/src/iwannaflycurses.messy b/src/iwannaflycurses.messy index 79f5c47..234deac 100644 --- a/src/iwannaflycurses.messy +++ b/src/iwannaflycurses.messy @@ -317,67 +317,6 @@ forever { } } -/* backslash enters console mode. characters are fetched and printed - * with ncurses, as well as stored in a temporary file. - * - * once the enter key is pressed, the temp file is rewound. - * a flex-generated parser is used to process the tokens. - * - * interpretation mode will change depending on the syntax. - * invalid commands may produce the response - * "Don't know how to ", amoungst others. - * - * a command will be provided to dump objects. - * text fields will show both their raw value and their text - * value in the correct encoding. using this comand to get - * out-of-character information is cheating, but no penalty - * can be implemented, as it would effect it's functionality. - * - * The internal debugger may produce intentional segfaults, - * which indicate a garbage pointer was dereferenced - * these should be called "dead canaries" in bugreports. - * these are useful in tracking down the most illusive of - * heisenbugs, as even if they cannot be directly observed, - * their modus operandi can be determined. - * - * only a number of expected variables may be dumped this way; - * true debugging should use GDB. - */ - -enum cli_argstypes -/* used to specify the type of the buffer that tokens are - * parsed into. types can be: - * - * argstype_wish (*heldobjtyp) (*heldobjtyp)[2] (*heldobjtyp)[4] - * argstyp_ent symtabref argstyp_equip equipenum - * - * container types will also allocate suitable contents - * once objid has been resolved - */ - -typedef cli_func *int(*void) - -enum commandenum -cli_func commandtable[256] -cli_argstypes commandargs[256] - -struct argstyp_wish { -uchar stack -objid type -void* data -} - -struct argstyp_ent { -bool shift -uchar race -bool stoned -} - -struct argstyp_equip { -equipenum slot -heldobjtyp* item -} - struct stringlistyp { (self) *prev (self) *next @@ -404,18 +343,13 @@ char* text } // like stringlistyp, but also has a field for eventident -/* typedef struct Rune { - * umint sym : 24; - * bool bold : 1; - * bool italic : 1; - * bool under : 1; - * bool strike : 1; - * bool over : 1; - * bool reverse : 1; - * bool blink : 1; - * bool invis : 1; - * } Rune; //not needed - */ +/*blackbox*/loading() + /* clears screen + * prints " LOADING..." on line 13 + * prints a hint on line 22. + * hints are stored in a struct + */ + uint util__roll (num,side,low) uchar num; //number of dice to roll @@ -505,6 +439,13 @@ return lines; * QAY, AQW, "A:, FUJ. if Q or A are present in this group, they will be [Q]uit ɛ̩̍ [A]bort, * swapping places with the other option. otherwise, the quit-abort-option3 order will be kept. */ + +union error_typ { +void* pointer; +const char* string; +intptr_t value; +} + ERROR_GRAPHIC(string,sign1,num1,sign2,num2,hard) char* string char sign1 sign2 @@ -513,28 +454,30 @@ bool hard { char* opt3 if (hard) { - attrset(COLOR_PAIR((BACKGROUND*COLOR_YELLOW)+COLOR_RED) + attrset(COLOR_PAIR((BACKGROUND*COLOR_RED)+COLOR_YELLOW+A_BLINK) opt3 = "Restart" } else { - attrset(COLOR_PAIR(BACKGROUND*COLOR_YELLOW) + attrset(COLOR_PAIR((BACKGROUND*COLOR_YELLOW)+COLOR_RED) opt3 = "Continue" } move(0,0); printw("*┐ Error!") move(1,0); printw("▗█▖ \"%s\"",string) switch sign1 : { -case 'u' : {move(2,0); printw("███ N1 = %u",num1);break;} -case 'i' : {move(2,0); printw("███ N1 = %+i",num1);break;} -case 'p' : {move(2,0); printw("███ N1 = %p",num1);break;} -case 'X' : {move(2,0); printw("███ N1 = $%08X",num1);break;} +case 'u' : {move(2,0); printw("███ N1 = %u",num1.value);break;} +case 'i' : {move(2,0); printw("███ N1 = %+i",num1.value);break;} +case 'p' : {move(2,0); printw("███ N1 = %p",num1.pointer);break;} +case 'X' : {move(2,0); printw("███ N1 = $%08X",num1.value);break;} +case 's' : {move(2,0); printw("███ %s",num1.string);break;} default : {move( 2,0); printw("███");break;} } switch sign2 : { -case 'u' : {move(3,0); printw("▝█▘ N2 = %u",num2);break;} -case 'i' : {move(3,0); printw("▝█▘ N2 = %+i",num2);break;} -case 'p' : {move(3,0); printw("▝█▘ N2 = %p",num2));break;} -case 'X' : {move(3,0); printw("▝█▘ N2 = $%08X",num2);break;} +case 'u' : {move(3,0); printw("▝█▘ N2 = %u",num2.value);break;} +case 'i' : {move(3,0); printw("▝█▘ N2 = %+i",num2.value);break;} +case 'p' : {move(3,0); printw("▝█▘ N2 = %p",num2.pointer));break;} +case 'X' : {move(3,0); printw("▝█▘ N2 = $%08X",num2.value);break;} +case 's' : {move(3,0); printw("▝█▘ %s",num2.string);break;} default : {move( 3,0); printw("▝█▘");break;} } move( 5,0); printw("File: %s",__FILE__) @@ -551,10 +494,12 @@ move(10,0); printw(" [Z] %s?",opt3) /*GLOBALS*/ playertyp PLAYER -coord3 PLAYERSHD //position of player's shadow, for renderer -latlontyp WORLD +latlontyp WORLDSWAP[23] +uchar WORLDSWPIN = 0 +#define WORLD WORLDSWAP[WORLDSWPIN] +#define CEILING ROOM->ceiling +roomstackholder ROOM_STACK roomtyp* ROOM -int(latlontyp)* ROOMGENCALL[ROOF + 1][EQUATOR/2 + 1][EQUATOR] shadowmask SHADOWKNOWS shadowmask SHINEALIGHT ullong TURN @@ -565,7 +510,7 @@ uchar ROOMTURN ullong KILLS char* SAVEPATH followtype *FOLLOW_ptr //pursuers, i.e. paid assasins, ninjas, the reaper... -eventtyp *EVNT_ptr //FOO_ptr refers to the doubly linked list's head. the tail is FOO_ptr->prev +eventtyp *EVNT_ptr //FOO_ptr refers to the doubly linked list's head. the tail is FOO_ptr->prev. FOO_ptr->prev->next is always NULL. placetyp *PLACE_ptr stringlistyp *HINT_ptr eventstringtyp *HEYLISTEN_ptr @@ -580,146 +525,9 @@ bitfield globools #define EVE globools.y #define MIDNIT globools.z -/* buffered room loading for future implementation: - * roomtyp* ROOMARRAY[3][3][3] - * #define ROOM ROOMARRAY[1][1][1] - * #define ROOM_NORTH ROOMARRAY[1][0][1] - * #define ROOM_NE ROOMARRAY[1][0][2]) - * #define ROOM_EAST ROOMARRAY[1][1][2] - * #define ROOM_SE ROOMARRAY[1][2][2] - * #define ROOM_SOUTH ROOMARRAY[1][2][1] - * #define ROOM_SW ROOMARRAY[1][2][0] - * #define ROOM_WEST ROOMARRAY[1][1][0] - * #define ROOM_NW ROOMARRAY[1][0][0] - * #define ROOM_UP ROOMARRAY[0][1][1] - * #define ROOM_UP_NORTH ROOMARRAY[0][0][1] - * #define ROOM_UP_NE ROOMARRAY[0][0][2] - * #define ROOM_UP_EAST ROOMARRAY[0][1][2] - * #define ROOM_UP_SE ROOMARRAY[0][2][2] - * #define ROOM_UP_SOUTH ROOMARRAY[0][2][1] - * #define ROOM_UP_SW ROOMARRAY[0][2][0] - * #define ROOM_UP_WEST ROOMARRAY[0][1][0] - * #define ROOM_UP_NW ROOMARRAY[0][0][0] - * #define ROOM_DOWN ROOMARRAY[2][1][1] - * #define ROOM_DOWN_NORTH ROOMARRAY[2][0][1] - * #define ROOM_DOWN_NE ROOMARRAY[2][0][2] - * #define ROOM_DOWN_EAST ROOMARRAY[2][1][2] - * #define ROOM_DOWN_SE ROOMARRAY[2][2][2] - * #define ROOM_DOWN_SOUTH ROOMARRAY[2][2][1] - * #define ROOM_DOWN_SW ROOMARRAY[2][2][0] - * #define ROOM_DOWN_WEST ROOMARRAY[2][1][0] - * #define ROOM_DOWN_NW ROOMARRAY[2][0][0] - * - * masks to select rooms - * #define UP_ROOMS_MASK ((umint) 0xFF400000) - * #define DOWN_ROOMS_MASK ((umint) 0x000002FF) - * #define NORTH_ROOMS_MASK ((umint) 0xC10C10C1) - * #define SOUTH_ROOMS_MASK ((umint) 0x1C01C01C) - * #define EAST_ROOMS_MASK ((umint) 0x70070070) - * #define WEST_ROOMS_MASK ((umint) 0x07007007) - * #define ALL_ROOMS_MASK ((umint) 0xFF4FF2FF) - * - * #define ROOM_NORTH_MASKBIT ((umint) 0x00080000) - * #define ROOM_NE_MASKBIT ((umint) 0x00040000) - * #define ROOM_EAST_MASKBIT ((umint) 0x00020000) - * #define ROOM_SE_MASKBIT ((umint) 0x00010000) - * #define ROOM_SOUTH_MASKBIT ((umint) 0x00008000) - * #define ROOM_SW_MASKBIT ((umint) 0x00004000) - * #define ROOM_WEST_MASKBIT ((umint) 0x00002000) - * #define ROOM_NW_MASKBIT ((umint) 0x00001000) - * #define ROOM_UP_MASKBIT ((umint) 0x00400000) - * #define ROOM_UP_NORTH_MASKBIT ((umint) 0x80000000) - * #define ROOM_UP_NE_MASKBIT ((umint) 0x40000000) - * #define ROOM_UP_EAST_MASKBIT ((umint) 0x20000000) - * #define ROOM_UP_SE_MASKBIT ((umint) 0x10000000) - * #define ROOM_UP_SOUTH_MASKBIT ((umint) 0x08000000) - * #define ROOM_UP_SW_MASKBIT ((umint) 0x04000000) - * #define ROOM_UP_WEST_MASKBIT ((umint) 0x02000000) - * #define ROOM_UP_NW_MASKBIT ((umint) 0x01000000) - * #define ROOM_DOWN_MASKBIT ((umint) 0x00000200) - * #define ROOM_DOWN_NORTH_MASKBIT ((umint) 0x00000080) - * #define ROOM_DOWN_NE_MASKBIT ((umint) 0x00000040) - * #define ROOM_DOWN_EAST_MASKBIT ((umint) 0x00000020) - * #define ROOM_DOWN_SE_MASKBIT ((umint) 0x00000010) - * #define ROOM_DOWN_SOUTH_MASKBIT ((umint) 0x00000008) - * #define ROOM_DOWN_SW_MASKBIT ((umint) 0x00000004) - * #define ROOM_DOWN_WEST_MASKBIT ((umint) 0x00000002) - * #define ROOM_DOWN_NW_MASKBIT ((umint) 0x00000001) - */ - /*end GLOBALS*/ -getlinebuffer (y,x) -uchar y x -{ -char* LINEBUFFER = calloc(BUFFER_MAX,sizeof(char)) -move(y,x) -int ch -forever { - ch = getch(); - if ((ch > UCHAR_MAX) || (ch < 0)) { - switch ch : { - case KEY_ENTER : move(y,x); fputc('\n',LINEBUFFER); rewind(LINEBUFFER); return 0; - case KEY_BACKSPACE : move(y,x); rewind(LINEBUFFER); return 4; - case KEY_HOME : move(y,x); rewind(LINEBUFFER); break; - case KEY_LEFT : move(y,x); rewind(LINEBUFFER); break; - case KEY_SLEFT : move(y,x); rewind(LINEBUFFER); break; - default : break; - } break; - } - else if (ch < ' ') { - switch ch : { - case 0x17 : move(y,x); rewind(LINEBUFFER); return 4; - case '\n' : move(y,x); fputc('\n',LINEBUFFER); rewind(LINEBUFFER); return 0; - case '\b' : move(y,x); rewind(LINEBUFFER); return 4; - default: break; - } - } - else { - fputc(ch,LINEBUFFER); - printw(ch); - } - } -free(LINEBUFFER) -} -umint getsixteen (y,x) -uchar y x -{ -char hexbuffer[8] = "00000000" -move(y,x-5);printw("[ - ]"); -int ch -uchar subscript = 0 -schar offset = subscript < 4 ? subscript-4 : subscript-3 -bool exiterr -forever { - ch = getch(); - if ((ch > UCHAR_MAX) || (ch < 0)) { - switch ch : { - case KEY_ENTER : goto(fin); - case KEY_BACKSPACE : subscript = INTVL(0,subscript-1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; - case KEY_LEFT : subscript = INTVL(0,subscript-1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; - case KEY_RIGHT : subscript = INTVL(0,subscript+1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; - case KEY_HOME : subscript = 0; offset = subscript < 4 ? subscript-4 : subscript-3; break; - case KEY_SLEFT : subscript = 0; offset = subscript < 4 ? subscript-4 : subscript-3; break; - case KEY_HOME : subscript = 7; offset = subscript < 4 ? subscript-4 : subscript-3; break; - case KEY_SRIGHT : subscript = 7; offset = subscript < 4 ? subscript-4 : subscript-3; break; - default : break; - } break; - } - else { - switch ch : { - case '\n' : goto(fin); - case '\b' : subscript = INTVL(0,subscript-1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; - case ' ' : subscript = INTVL(0,subscript+1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; - default: if (isxdigit(ch)) {hexbuffer[subscript] = ch; printw(ch);}; subscript = INTVL(0,subscript+1,7); offset = subscript < 4 ? subscript-4 : subscript-3; break; - } - } - move(y,x+offset); - } -fin: -return (umint) strtoul(hexbuffer,NULL,16); -} struct turntyp: uchar sec : 6 @@ -766,7 +574,7 @@ DAY = ((6 ≤ DATE.hour) && (DATE.hour < 18)) NIGHT = ((DATE.hour < 6) || (18 ≤ DATE.hour)) } -//cartesian projection, ->x ↓y ↑z (+y=-z) +//projection, →x ↓y ↑z struct coord3: uchar x @@ -886,14 +694,17 @@ struct latlontyp { uchar dep : 8 //0 ≤ dep ≤ 201 schar lat : 8 //-90 ≤ lat ≤ 90 sshort lon : 9 //-180 ≤ lon < 179 -bool shift : 1 //are you plane shifted? -bool moon : 1 //are you on the moon? -uchar az : 3 //azimuth on a plane chart +uchar shift : 2 //are you plane shifted? +uchar az : 3 schar el : 2 } /* in-game altitude is given as the distance from layer 100 * - * when combined with shift, moon becomes outer planes + * shift 0 is the prime plane + * shift 1 are the elemental planes + * shift 2 are afterlives + * shift 3 can be used for areas that are meant to not show up on a map. + * (said map is WIP) * * az elemental afterlife corrilation * 0 water neutral good nurturer @@ -917,6 +728,22 @@ schar el : 2 * errors related to this section may generate one of 2 errors: * "fell off the edge of the world", N1=±lat,N2=±lon * "froze to death on pluto", N1=+az,N2=±el + * + * a room stack exists that keeps a number of rooms loaded + * if a room is not on the stack, it is loaded from the save file and + * pushed to the stack. this may cause the stack to intentionally drop + * the room at the bottom to prevent eating too much ram. if the file + * does not yet exist, the room is generated by perl according to a + * dispatch table or a similarly supplied lookup method. if no constructor + * exists, an error occurs. if the constructor is actually a death call, + * you die. + * + * a swap array keeps track of gating between the 23 major planes, + * saving the player's position, but not keeping the room loaded. + * + * connectivity of rooms is in 7 directions: the 6 euclidian directions + * and a room which can be accessed by a 180° phase shift. if NULL, + * scrolling in that direction is blocked. */ struct placetyp { @@ -933,9 +760,6 @@ ushort gp : 17 uchar cp : 7 } -#define GOLDMAX = 130999 -#define COPPERMAX = 99 - struct aligntyp: good : b1 evil : b1 @@ -1032,8 +856,6 @@ ptrtab mon1table * becoming polylocked to one of the C0 entrys has no negative effects. * commands can change your base race without negative side effects * - * polymorph autocomplete is implemented using switches. - * * entities can only be polymorphed into things in their own table. * this is due to a software limitation that will not be fixed, * as it enables species to easily be sorted into polymorphable @@ -1683,7 +1505,7 @@ bool multiuse : 1 bool scroll : 1 uchar subject : 2 //0 = cooking, 1 = weapons, 2 = language, 3 = spellcraft uchar uses : 6 -*void contents +void* contents char* wandmaterials[16] = {"oak","ash","yew","honeylocust","silver","bronze","iron","orichalcum","marble","bone","dragon fang","unicorn horn","glass","lead crystal","adamantine","stardust"} //stoning -> marble @@ -1700,11 +1522,44 @@ uchar matter : 3 uchar color : 3 paffectyp enchnt +struct roomneighbors { +bool north +bool south +bool east +bool west +bool up +bool down +bool upstair +bool downstair +latlontyp north +latlontyp south +latlontyp east +latlontyp west +latlontyp up +latlontyp down +latlontyp mirror +} + +struct roomstack { +struct roomstack* prev; +struct roomstack* next; +latlontyp key; +roomtyp* value; +} + +struct roomstackholder { +struct roomstack* bottom; +struct roomstack* top; +ushort depth; +} + struct roomtyp: //top-down display of a 3d space latlontyp latlon tileset *hightiles schar* tiledata[][MAX_Y][MAX_X] -uchar ceiling +uchar ceiling : 4 +uchar floorcolor : 3 +bool visited : 1 shadowmask seen encontyp *encon_ptr enttyp *ent_ptr @@ -1715,13 +1570,7 @@ setcoord3 *path_ptr coord2 downstair coord2 upstair coord3 home -bool do_upstair : 1 -bool do_downstair : 1 -bool visited : 1 -bool blank : 1 -bool shadefloor : 1 -uchar floorcolor : 3 -uchar meta //may be used by events +struct roomneighbors neighborhood /* if invalid coords are given for a warp (typically {$FF,$FF}), * then the player is dumped at the location indicated by home. * @@ -1766,7 +1615,7 @@ lightyp *lamp_ptr * *.d : everything relating to a struct is stored in the same directory, and pointers to structs are stored as subdirectories with the name of that field. the tail element in a linked list has no subdirectory named "next"; "prev" pointers are "../" implicitly. * *.conf : a configuration file, parsed with perl. * *.*rc : a user's configuration file. - * *.dump : a debugger data dump, with a format somwhere between JSON, INI, and C-like pseudocode. essentialy a dat file in readable (and non-raw) format. + * *.dumper : a debugger data dump, with a format somwhere between JSON, INI, and C-like pseudocode. essentialy a dat file in readable (and non-raw) format. * * if the following new extensions collide with anything, I will change them. I specifically chose ones that were not a TLA or EFLA to try and avoid this, because there have been TDMTLA since before I came along. * *.midibas : midiBASIC, to be parsed by the midi generator into a .h file. Represents a different subset of general midi than regular midi files, but does so in a human readable format. @@ -2196,15 +2045,15 @@ an UNDERLINE is a shadow note: unicode symbols are (mostly) used be their appearence, not by their meaning ) is a sword or dagger. ⍏ are polearms. \ is a staff. ¦ is a club. : is a mace. ℓ is a whip. ( is a bow. ⇤ is an arrow. ⍖ is a writing instrument. ⟦ is armor. [ is clothing. ] is a shield. ⟧ are cannons or greeves. % is meat. ⊞ is food (don't shoot it). $ is gold. ¢ is copper. -? is a misc item. ↧ is a digging tool. ⌥ is a key or lockpick. ♫ is a lyre. ƒ is a violin. ♪ is a different music instrument. +⌘ is a misc item. ↧ is a digging tool. ⌥ is a key or lockpick. ♫ is a lyre. ƒ is a violin. ♪ is a different music instrument. ¿ are potions (fragile). ∫ is a scroll. ⊒ is a book. ∩ is a tablet. ° is a ring. º is a bracelet. ª is an amulet. ^ is a crown. / is a wand. ♮ is a ladder. ⋎ is a fountain or gyser. ⍾ is a bell. ⎋ is a clockface. ♠ ♣ ‡ are trees. ⋏ is fire. ♜ is a pedestal. ≋ is deep liquid's surface. ∬ is a waterfall. ≈ is a shallow liquid's surface, or a deep liquid below surface. ~ (centered) is a puddle. ≣ is a staircase. ⌁ is electricity. * is ice. ⎈ spider web. ⌬ beehive. ↥ are spikes. ⎙ ⍝ ⎍ ∎ ⎅ are tombstones or signs. ␥ is glass. ! is trouble. ☀ is a light source. ⌸ is a door. ⍯ is a locked door. ⎕ is an open door. = is a gate. ≠ is a locked gate. ∷ is an open gate. • is a boulder. . is a rock. ⁂ is a rockslide. ◇ is a gemstone. ◊ is a giant magic crystal. ⑆ are footprints. -∪ is a sink. ⏍ is a chest. ↯ is the thunderbolt. ∅ is a spacetime anomaly (do not touch). < > are level stairs. ⌘ is home. -← ↑ → ↓ ↖ ↗ ↘ ↙ are flying projectiles. ⇐ ⇑ ⇒ ⇓ ⇖ ⇗ ⇘ ⇙ are ballistae. ✪ is a rune. ː ⍽ are traps. +∪ is a sink. ⏍ is a chest. ↯ is the thunderbolt. ∅ is a spacetime anomaly (do not touch). < > are level stairs. +← ↑ → ↓ ↖ ↗ ↘ ↙ are flying projectiles. ⇐ ⇑ ⇒ ⇓ ⇖ ⇗ ⇘ ⇙ are ballistae. ✪ is a rune. ː ⍽ are traps. ? is somone wearing a cloak. # █ ▓ ▒ ░ ▞ ▚ (etc) are thick walls or floor. ≎ ☈ are clouds (do not walk on them; keep your head out of them). ˜ ␣ are holes. ' is a stalagtite or icicle. , is a plant. ; is a grain or sunflower (impassable). box drawings are low walls or columns. ⑉ ⋮ are iron bars. · is an ember or star. ` ´ are flower petals. @@ -2326,34 +2175,6 @@ jelly* jam* preserves* peanutbutter icecube snow ember blacksoup broth* stew* ration mistake -/*ROTTEN pseudocode*/playermove(xmove,ymove,zmove) -schar xmove -schar ymove -schar zmove -{ -velocitycheck() -xymovecheck(xmove,ymove) -zmovecheck(zmove) - -PLAYER.pos.x += xmove -if (PLAYER.pos.x < 0) { - PLAYER.pos.x = mapscroll(-1,0).x - - } -else if (PLAYER.pos.x ≥ MAX_X) { - PLAYER.pos.x = mapscroll(1,0).x - } - -PLAYER.pos.y += ymove -if (PLAYER.pos.y < 0) { - PLAYER.pos.y = mapscroll(0,-1).y - } -else if (PLAYER.pos.y ≥ MAX_Y) { - PLAYER.pos.y = mapscroll(0,1).y - } - -PLAYER.pos.z += zmove -} /*blackbox*/playervelocitycheck() velocitycheck(*entity) /* if you have a nonzero velocity vector, when you try to move @@ -2389,130 +2210,17 @@ PLAYER.pos.z += zmove - if you are, adds {-xmove,-ymove,-zmove} to your velocity (half this value in liquids) -/*rotten pseudocode*/mapwarp(destination,tocoord) -latlontyp destination -coord3 tocoord +roomscroll(direction,stairs) +uchar direction +bool stairs { -saveroom() +switch (direction) : { + case 0 : break; + case ROOM_UP : saveroom(NULL);WORLD = touchroom(ROOM->neighborhood->up); -WORLD = destination +roomwarp(latlontyp) -mapscroll(NOSCROLL) - -loadroom(WORLD) - -if ((tocoord.x > MAX_X) || (tocoord.y > MAX_Y) || (tocoord.z ≥ CEILING)) { - PLAYER.pos.x = ROOM.home.x - PLAYER.pos.y = ROOM.home.y - PLAYER.pos.z = ROOM.home.z - } -else { - PLAYER.pos.x = tocoord.x - PLAYER.pos.y = tocoord.y - PLAYER.pos.z = tocoord.z - } -} - -/*blackbox*/loading() - /* clears screen - * prints " LOADING..." on line 13 - * prints a hint on line 22. - * hints are stored in a struct - */ - -struct mapscrollargs { -schar latmove : 2 -schar lonmove : 2 -schar depmove : 2 -bool stair : 1 -bool home : 1 -} - -mapscrollargs NOSCROLL = {0,0,0,false,false} - -/*implicit*/mapscroll(args) -mapscrollargs args -{ -BREAKCURSES -if (IS_XTERM) {printf("\033]2;IWannaFlyCurses - %s: loading...\033\\",GAMENAME);} -printf("loading..."); -fflush(stdout); -FIXCURSES -saveroom(NULL) -freeroom(NULL) -WORLD.coord.lat += args.latmove -if (WORLD.coord.lat > EQUATOR/4) { - WORLD.coord.lat = EQUATOR/2 - WORLD.coord.lat - WORLD.coord.lon += EQUATOR/2 - if (WORLD.coord.lon > EQUATOR/2) { - WORLD.coord.lon += -EQUATOR - } - } -else if (WORLD.coord.lat < -EQUATOR/4) { - WORLD.coord.lat = -EQUATOR/2 - WORLD.coord.lat - WORLD.coord.lon += EQUATOR/2 - if (WORLD.coord.lon > EQUATOR/2) { - WORLD.coord.lon += -EQUATOR - } - } - -WORLD.coord.lon += args.lonmove -if (WORLD.coord.lon ≥ EQUATOR/2) { - WORLD.coord.lon += -EQUATOR - } -else if (WORLD.coord.lon < -EQUATOR/2) { - WORLD.coord.lon += EQUATOR - } - -if ((args.depmove < 0) && (WORLD.coord.dep = 0)) { - depmove = 1 - WORLD.coord.lat = -WORLD.coord.lat - if (WORLD.coord.lon == -EQUATOR/2) {WORLD.coord.lon = 0} - else {WORLD.coord.lon = -WORLD.coord.lon} - } -else if ((args.depmove > 0) && (WORLD.coord.dep = ROOF)) { - /* death message (one of the following): - * flew too close to the sun - * was smited for rising too high - * grew too proud - * passed out in space and burned up on reentry - * froze to death in outer space - * became lost...in...spaaace! - */ - } -WORLD.coord.dep += args.depmove -if (depmove ≥ 0) : { - if (home) { - PLAYER.pos.x = ROOM.home.x - PLAYER.pos.y = ROOM.home.y - else if (stair) { - PLAYER.pos.x = ROOM.downstair.x - PLAYER.pos.y = ROOM.downstair.y - } - PLAYER.pos.z = 0 - } -else { - if (home) { - PLAYER.pos.x = ROOM.home.x - PLAYER.pos.y = ROOM.home.y - else if (stair) { - PLAYER.pos.x = ROOM.upstair.x - PLAYER.pos.y = ROOM.upstair.y - } - PLAYER.pos.z = CEILING - } - -ROOM = loadroom(WORLD) - -NEW = true -FIRST = !(visited) -ROOM.visited = true - -BREAKCURSES -if (IS_XTERM) {printf("\033]2;IWannaFlyCurses - %s: %i°%c, %i°%c, %i\033\\",GAMENAME,abs(WORLD.lat),WORLD.lat > 0 ? 'N' : (WORLD.lat < 0 ? 'S' : ' '),WORLD.lon > 0 ? 'E' : ((WORLD.lon < 0) && !(WORLD.lon == -180) ? 'W' : ' '),WORLD.dep - 100); -FIXCURSES -render(); -} +coordjump(coordx,coordy,coordz) /*blackbox*/saveroom(roomtyp*) //saves the room pointed to, or the current room if NULL @@ -2592,9 +2300,95 @@ if (roomptr == NULL) {roomptr = ROOM} roomtyp* loadroom(latlontyp) //loads room indicated by WORLD -/*blackbox*/saveworld() -/*blackbox*/loadworld() -//sync and load the files for planes +swaproom(dest) +struct latlontyp dest; +{ +if (!(dest.shift || dest.az || dest.el)) {WORLDSWPIN = 0} +else {switch dest.shift : { + case 0 : return ERR; + case 1 : if (!(dest.el)) { + switch dest.az : { + case 0 : ROOMSWPIN = 1; return OK; + case 01 : ROOMSWPIN = 2; return OK; + case 02 : ROOMSWPIN = 3; return OK; + case 03 : ROOMSWPIN = 4; return OK; + case 04 : ROOMSWPIN = 5; return OK; + case 05 : ROOMSWPIN = 6; return OK; + case 06 : ROOMSWPIN = 7; return OK; + case 07 : ROOMSWPIN = 8; return OK; + default : ERROR_GRAPHIC("Struct Field Overflow",'X',dest.az,'s',"too big for expected three bit field",true); + } + else if (dest.el && !(dest.az)) { + case 1 : ROOMSWPIN = 9; return OK; + case -1 : ROOMSWPIN = 10; return OK; + case -2 : ROOMSWPIN = 11; return OK; + default : ERROR_GRAPHIC("Struct Field Overflow",'X',dest.el,'s',"too big for expected three bit field",true); + } + break; + case 2 : if (dest.az && !(dest.el)) { + switch dest.az : { + case 0 : ROOMSWPIN = 12; return OK; + case 01 : ROOMSWPIN = 13; return OK; + case 02 : ROOMSWPIN = 14; return OK; + case 03 : ROOMSWPIN = 15; return OK; + case 04 : ROOMSWPIN = 16; return OK; + case 05 : ROOMSWPIN = 17; return OK; + case 06 : ROOMSWPIN = 18; return OK; + case 07 : ROOMSWPIN = 19; return OK; + default : ERROR_GRAPHIC("Struct Field Overflow",'X',dest.az,'s',"too big for expected three bit field",true); + } + else if (dest.el && !(dest.az)) { + case 1 : ROOMSWPIN = 20; return OK; + case -1 : ROOMSWPIN = 21; return OK; + case -2 : ROOMSWPIN = 22; return OK; + default : ERROR_GRAPHIC("Struct Field Overflow",'X',dest.el,'s',"too big for expected three bit field",true); + } + break; + default : return ERR; + }} + +roomstackpush(newkey,newval) +latlontyp newkey +roomtyp* newval +{ +struct roomstack* newnode = malloc(sizeof(struct roomstack)); +newnode->key = newkey; +newnode->value = newval; +newnode->prev = ROOM_STACK->top; +newnode->next = NULL; +ROOM_STACK.top->next = newnode; +ROOM_STACK.top = ROOM_STACK.top->next; +ROOM_STACK.depth++; +if (ROOM_STACK.depth > ROOM_STACK_MAX) { + roomstackshift(); + ROOM_STACK--; + } +} + +roomstackpop() +roomstackshift() +roomstacksearch(latlontyp) +roomstackpunt(roomstack*) +room_p(latlontyp) +roomgen(latlontyp) + +roomtyp* touchroom(query) +latlontyp query +{ +roomstack* answer = roomstacksearch(query); +if (answer != NULL) { + roomstackpunt(answer); + return ROOM_STACK.top.value; + } +else if (room_p(query)) { + roomstackpush(query,loadroom(query)); + return ROOM_STACK.top.value; + } +else { + roomstackpush(query,roomgen(query)); + return ROOM_STACK.top.value; + } +} /*blackbox*/loadgame() /*blackbox*/savegame() diff --git a/src/macro.h b/src/macro.h index 729584d..010b270 100644 --- a/src/macro.h +++ b/src/macro.h @@ -18,6 +18,11 @@ #define ≤ <= #define forever for (;;) +/* syntactic sugar for macros that are actually tailcalls + * such macros contain a return or this macro + */ +#define tailcall(X) X + #ifndef EOF #error now you're just TRYING to break stuff... #endif @@ -92,7 +97,7 @@ DEADBEEF->prev->next = DEADBEEF->next;\ }\ free(DEADBEEF);\ - }\ + }\ #define MACRO__DLLIST_INSERT(PREV,NEW) {\ NEW->prev = PREV;\ diff --git a/src/modules/IWannaFly/LinkedList.pm b/src/modules/IWannaFly/LinkedList.pm index 53c7c6c..11bc31b 100644 --- a/src/modules/IWannaFly/LinkedList.pm +++ b/src/modules/IWannaFly/LinkedList.pm @@ -122,76 +122,103 @@ sub Set { return $self->Here; } -# Linked lists are provided using objects with methods: -# ->Head is the first element; or an alias of ->Here for ¢ and § -# ->Tail is the last element, an alias of ->Here->{prev} for §, or a cached node whose ->{next} is equal to ->Here for ¢ -# ->Offset($) element $-offset from ->Head -# ->Here is the currently indexed element. -# ->FromHere($) element $-offset from ->Here -# ->Index the offset index from ->Head of ->Here. always 0 for § and ¢. -# ->Size the number of elements in the list. - -# ->Adv advances ->Here by 1 -# ->Rew rewinds ->Here by 1 -# ->Seek($) changes ->Here by $ -# ->Reset resets ->Here to ->Head. -# ->Set($) set ->Here to ->Head + $. - -# ->Push adds a new element after ->Tail with the same keys as ->Head. -# ->PushHere adds a new element after ->Here with the same keys as ->Head and moves to it. -# ->PushTo($) adds a new element at ->Offset($) with the same keys as ->Head. -# ->PushToHere($) adds a new element at ->FromHere($) with the same keys as ->Head. -# ->Shove adds a new element before ->Head with the same keys as ->Head. - -# ->Pop removes ->Tail, or the node immidiately before ->Here for § and ¢ + + +# Doubly linked lists +# £§->Head is the first element; alias of Here for wheel lists. +# £§->Tail is the last element; alias of Prev for wheel lists. +# §->Prev is the previous element; +# £§->Next is the next element; +# £§->Offset($) element $-offset from ->Head. may be negative to indicate tail in § +# £§->Here is the currently indexed element. +# £§->FromHere($) element $-offset from ->Here. may be negative to look backwards in § +# £§->Index the offset index from ->Head of ->Here. +# £§->Size the number of elements in the list. +# £§->All the list elements as an array of ->Size + +# £§->Adv advances ->Here by 1 +# §->Rew rewinds ->Here by 1 +# £§->Seek($) changes ->Here by $. may be negative to seek backwards in § +# £§->Reset resets ->Here to ->Head. does nothing in wheel lists. +# £§->SeekTo($) set ->Here to ->Head + $. may be negative in §. + +# ->Set(%) sets the values of Here according to % +# ->SetAt($%) sets the values of ->Offset($) according to % +# ->SetFrom($%) sets the values of ->FromHere($) according to % + +# ->Push([%]?) adds a new element after ->Tail with the same keys as ->Head; if % is present, initialize to those values +# ->PushHere([%]?) adds a new element after ->Here with the same keys as ->Head and moves to it. +# ->PushTo($[%]?) adds a new element at ->Offset($) with the same keys as ->Head. may be negative. +# ->PushToHere($[%]?) adds a new element at ->FromHere($) with the same keys as ->Here. +# ->Shove([%]?) adds a new element before ->Head with the same keys as ->Head. + +# ->Pop removes ->Tail # ->PopHere removes ->Here -# ->PopAt($) removes ->Offset($) +# ->PopAt($) removes ->Offset($). may be negative. # ->PopFrom($) removes ->FromHere($) # ->Axe removes ->Head -# ->Punt sends ->Here to ->Tail (Do not pass go do not collect 200 scalars.) Alias of ->Adv for § -# ->PuntAt($) sends ->Offset($) to ->Tail -# ->PuntFrom($) sends ->Fromhere($) to ->Tail, or to before ->Here for § and ¢ -# ->Put($) sends ->Here to ->Offset($) -# ->Throw($) sends ->Here to ->FromHere($) -# ->Move($) seeks by $ while still holding ->Here +# ->Punt sends ->Here to ->Tail. +# ->PuntAt($) sends ->Offset($) to ->Tail. +# ->PuntFrom($) sends ->FromHere($) to ->Tail. +# ->Put($) sends ->Here to ->Offset($). +# ->Throw($) sends ->Here to ->FromHere($). +# ->Move($) seeks by $ while still holding ->Here. -# ->Pull($) pull ->Offset($) to before ->Here -# ->PullFrom($) pull ->FromHere($) to before ->Here +# ->Pull($) pull ->Offset($) to between ->Here and ->Next. becomes ->Here. +# ->PullFrom($) pull ->FromHere($) to between ->Here and ->Next. becomes ->Here. -# ->Flip($) swaps ->FromHere($) and ->Here -# ->Flop($) swaps ->Offset($) and ->Here -# ->Swap swaps ->Tail and ->Here. -# ->Switch swaps ->Head and ->Here. -# any combination of (Flip|Flop|Swap|Switch)(Flip|Flop|Swap|Switch) except (Swap|Switch)(Swap|Switch) swap the non-here elements, with the args in that order. +# ->Kick swaps ->Here and ->Prev +# ->Swap($$$$) swaps 2 entries; $_[1] and $_[3] are FromHere, Offset, Head, Here, Tail, Next, or Prev ; $_[2] and $_[4] are intergers for Offset and FromHere, or ignored for the others. # ->FlushAll syncs all elements to their pointers +# ->BigRedButton frees and undefs contents of list, same as free_recurse() # classes for linked list objects are: -# IWannaFly'LinkedList::Single -# IWannaFly'LinkedList::SingleCircle -# IWannaFly'LinkedList::Double -# IWannaFly'LinkedList::DoubleHalf -# IWannaFly'LinkedList::DoubleCircle + +# creates £ +# IWannaFly::LinkedList::Single::Bounded +# IWannaFly::LinkedList::Single::Circle +# IWannaFly::LinkedList::Single::Wheel + +# creates § +# IWannaFly::LinkedList::Double::Bounded +# IWannaFly::LinkedList::Double::HalfCircle +# IWannaFly::LinkedList::Double::Circle +# IWannaFly::LinkedList::Double::Wheel +# IWannaFly::LinkedList::SingleAsDouble::Bounded +# IWannaFly::LinkedList::SingleAsDouble::HalfCircle +# IWannaFly::LinkedList::SingleAsDouble::Circle +# IWannaFly::LinkedList::SingleAsDouble::Wheel # each linked list class supports: -# ::capture(%) makes a container around a recursive hash, with members -# named ->{next} containing the recursion, as are created by the -# data file parsers. ->{prev} members may be overwritten, and if -# the formatting does not match, this could cause a resource -# starvation loop, i.e., capturing a circularly linked list with -# the non-circular class. +# ::capture($%) makes a container named $ around a recursive hash, with +# members named ->{next} containing the recursion, as are created by +# fetch. ->{prev} members are ignored, and if the formatting does +# not match, this could cause a resource starvation loop, i.e., +# capturing a circularly linked list with the non-circular class. +# ::new($) creates a new empty container named $. empty linked lists are +# handled specially, similar to undef, '', or [] +# ::fetch($°) same as fetch below # the following are avalible for structs or linked list elements: -# ->{Ptr} is the C pointer to the struct. +# ->Ptr is the C pointer to the struct. # ->Flush syncs a struct object to its pointer. +# ->Refresh fetches the data at the pointer and overrides the +# current object state +# ->Clone($) creates a duplicate of the object and name it $ +# ->BlankClone($) create a blank duplicate of the object and name it $ # each struct class supports: -# ::new makes an empty locked hash object with the fields of the struct, -# the additional field ->{Ptr}, and the method ->SYNC. -# ::fetch(°) creates a new container from the data at °. pointer fields -# are replaced with perl references to an object created in the same -# manner; null pointers are translated to undef, and undef is -# translated to null. +# ::new($) makes an empty locked hash object with the fields of the struct, +# and the additional fields and methods above. +# ::fetch($°) creates a new container named $ from the data at °. +# pointer fields are replaced with perl references to an object +# created in the same manner; NULL pointers are translated to undef, +# and undef is translated to NULL. keeps a list of addresses parsed, +# and terminates upon a double occurence or being told to get data at +# NULL, thus enabling the loading of non-garbled linked lists. # ::malloc and ::calloc return a pointer address to a struct of that type # ::capture(\%) makes a container around a hash diff --git a/src/modules/IWannaFly/Main.pm b/src/modules/IWannaFly/Main.pm index c937d56..413eeb2 100644 --- a/src/modules/IWannaFly/Main.pm +++ b/src/modules/IWannaFly/Main.pm @@ -19,13 +19,8 @@ our @EXPORT; -# ‰foo is a hash ref or struct -# £foo is a singly linked list object -# ¢fie is a singly, circularly linked list object -# ♮bam is a doubly linked list -# €baz is a doubly, half-circularly linked list -# §qux is a doubly, circularly linked list -# ¤zot is a reference -# °abc is a C pointer -# ¶zyz is a regex +# £foo is a singly linked list +# §bar is a doubly linked list +# ¤qux is a C pointer +# ¶zot is a regex diff --git a/src/modules/MyUtils/Macro.pm b/src/modules/MyUtils/Macro.pm index 7f4cfc2..1e44387 100644 --- a/src/modules/MyUtils/Macro.pm +++ b/src/modules/MyUtils/Macro.pm @@ -22,15 +22,10 @@ sub CLAMP($$$) {return MIN( MAX( $_[0],$_[1] ),$_[2] )} FILTER_ONLY code_no_comments => sub { s/≤/<=/g }, code_no_comments => sub { s/≥/>=/g }, - code_no_comments => sub { s/‰/\$/g }, - code_no_comments => sub { s/°/\$/g }, code_no_comments => sub { s/¤/\$/g }, - code_no_comments => sub { s/¢/\$/g }, - code_no_comments => sub { s/♮/\$/g }, code_no_comments => sub { s/£/\$/g }, - code_no_comments => sub { s/€/\$/g }, code_no_comments => sub { s/§/\$/g }, code_no_comments => sub { s/¶/\$/g }, code_no_comments => sub { s/T(?:rue|RUE)/true/g }, code_no_comments => sub { s/F(?:alse|ALSE)/false/g }, - code_no_comments => sub { s/(?:^|(?<=[\{]))((?:[\w]+[:])?[\s]*)forever/$1for (;;)/gm }; + code_no_comments => sub { s/forever/for (;;)/gm }; diff --git a/src/modules/MyUtils/Null.pm b/src/modules/MyUtils/Null.pm index 5996df6..e0fdecd 100644 --- a/src/modules/MyUtils/Null.pm +++ b/src/modules/MyUtils/Null.pm @@ -7,7 +7,7 @@ use MyUtils::NullXS; require Exporter; our @ISA = qw(Exporter); -our @EXPORT = qw(NULL free); +our @EXPORT = qw(NULL free freeItr); sub NULL { return MyUtils::NullXS::myperlxs__null(); @@ -16,3 +16,22 @@ sub NULL { sub free($) { MyUtils::NullXS::myperlxs__free($_); } + +sub freeItr { + my $arg = shift; + my $error = 0; + foreach (keys %$arg) { + if (reftype($arg->{$_}) eq 'HASH') { + recursivefree($arg->{$_}); + } + else { + $error++; + } + } + unless ($error) { + if (exists($arg->{Ptr})) { + free($arg->{Ptr}); + } + } + return $error; + }