diff --git a/assets.h b/assets.h index f25dfe5..5968f3f 100644 --- a/assets.h +++ b/assets.h @@ -164,6 +164,91 @@ static const char *LCR_internalDataFile = ":-w5u:f31d" ":'w5G:f311" + // MAP 2: + "#MLC2;4321 1" + ":*qrt:!o1y:!o1z:+Wsz" + // start box: + ":=mqr:f96d:xnrs:f74b:^mvrJ:f11d:^uvrL:f11d" + ":~ouz3- :~suz3- :~ouw3- :~suw3-" // lights + ":^utuI-:^utv-:^utzI-:^utA-" + ":'ustI:-usu:-usv:'usw" + ":'usyI:-usz:-usA:'usB" + ":xpvA:f313" + ":upvAL:urvAI:urvCJ:upvC" + ":opqz:f314" + ":^pwAI-:f311:^pwz:f311" + ":^pxBI-:f311:^pxA:f311" + ":^pyCI-:f311:^pyB:f311" + ":^pzDI:f311:^pzC:f311" + // start bridge: + ":'ovEI:f511:IrL:f514" + ":^orPI-:fB11" + ":AKtL2|I:m111:AStP2|I:m111:IPsL2:IVsN2" // pillars + ":-UrC3-:f518:'UrJ3-:f511:'UrC3I-:f511" // fozen bridge + ":=Urw2:f516" // dirt + ":|Ysw2J:f11k" // fence + ":=vrK1:f713" + // loop: + ":]FsNJ:f113:|FtNJ:f113" + ":]FwNJ-:f113:|FvNJ-:f113" + ":]DsKL:f113:|DtKL:f113" + ":]DwKL-:f113:|DvKL-:f113" + ":-DxK:f316" + ":;CsK|:f153" + ":;GsN:f153" + ":,CxK|:f116" + ":,GxK:f116" + ":}FsNJ:}DsML:|EsM2:|EsN2I" + ":ICsPI:f151:IGsK:f151" + // downhill: + ":^TrwJ:f116:^TqwL-:f116" + ":^SqwJ:f116:^SpwL-:f116" + ":^RpwJ:f116:^RowL-:f116" + ":^QowJ:f116:^QnwL-:f116" + ":^PnwJ:f116:^PmwL-:f116" + ":^OmwJ:f116:^OlwL-:f116" + ":^NlwJ:f116:^NkwL-:f116" + ":^MkwJ:f116:^MjwL-:f116" + ":^LjwJ:f116:^LiwL-:f116" + ":^KiwJ:f116:^KhwL-:f116" + ":^JhwJ:f116:^JgwL-:f116" + ":^IgwJ:f116:^IfwL-:f116" + ":=Hfw2:f116" + ":^GfwJ:f116:^GewL-:f116" + ":^FewJ:f116:^FdwL-:f116" + ":^EdwJ:f116:^EcwL-:f116" + ":^DcwJ:f116:^DbwL-:f116" + ":^CbwJ:f116:^CawL-:f116" + ":^BawJ:f116:^B9wL-:f116" + ":^A9wJ:f116:^A8wL-:f116" + ":^z8wJ:f116:^z7wL-:f116" + ":^y7wJ:f116:^y6wL-:f116" + ":yx6wJ:f116:^x5wL-:f116" + ":yw5wJ:f116:^w4wL-:f116" + ":yv4wJ:f116:^v3wL-:f116" + ":^u3wJ:f116:^u2wL-:f116" + ":^t2wJ:f116:^t1wL-:f116" + ":^s1wJ:f116:^s0wL-:f116" + // bumps on downhill: + ":oDcB:f121" + ":=Fey:f121" + ":oJhw:f121" + ":=KiA:f121" + ":=Mkx" + ":=Pny:f121" + // finish platform: + ":=n0w:f516:=o0y1:=o0z1" + ":Ap1x2L:f141:Aq1w2L:f141:Ap1w2J:f141" + ":Ap1A2:f141:Aq1B2:f141:Ap1B2I:f141" + /* tiny maps, max: - 400 character string - 512 blocks diff --git a/media/manual.txt b/media/manual.txt new file mode 100644 index 0000000..b97c35a --- /dev/null +++ b/media/manual.txt @@ -0,0 +1,145 @@ +WORK IN PROGRESS + +-._.-'"'-._.-'"'- LICAR MANUAL -'"'-._.-'"'-._.- + +by drummyfish, released under CC0 1.0, punlic domain + +~~~ GENERAL ~~~ + +Licar is a relatively simple 3D stunt racing game inspired by other popular +games of this genre. Unlike most games in existence, Licar is completely free +as in freedom (meaning its source code is available for any use), gratis, and +its focus lies on being well programmed by employing minimalism and rejecting +harmful "modern" programming practice. The game aims to seflessly bring +happiness to all people, even those who have no money, own only very old and +weak computers etc. It is not a commercial product and has been made purely out +of love by a single man. + +The game runs on many platforms and comes in different versions depending on +what the platforms allow. Some versions may have more features or visual +"richness" than others. If anything mentioned in this manual is missing in your +game, it's probably because of limitations of your platform. On PCs and laptops +however everything should be supported. + +~~~ RUNNING ~~~ + +There are compiled versions of Licar for many different platforms. If yours +is among them, running the game should be as simple as running any other +program. + +If there isn't a version for your system or for some other reason you can't +run the game, you may try to compile the game yourself from the source code. +This is very easy (unlike with most "modern" software), it usually involves +typing a command in command line. For more detail check out the README. + +Note that it's also possible to play the game in a web browser or through some +kind of compatibility layer or emulator if there is no native executable for +your system. + +If you know what command line arguments are, you may also check them out by +running the game with -h argument. This will allow you to for example start the +game and immediately load a map, which is handy when creating new maps. + +~~~ OBJECTIVES ~~~ + +In Licar, unlike in most other racing games, you only race against time, i.e. +you are alone on the track. There is an option to race against a replay ghost, +but the ghost still cannot collide with your car, so the point remains that your +final time depends purely on how well you drive, opponents cannot spoil your +results by crashing with you or blocking your path. + +The objective of every map is to drive from start to finish (red octahedron) as +fast as possible while collecting all the checkpoints (CP, green octahedron) +along the way (in any order). There is always a target time which you're trying +to beat in the bottom left of the screen. If you beat the time, you have +achieved the goal, your replay is automatically saved and your new time becomes +the next target time. + +Your run can be restarted at any time. Typically you will need hundreds of +attempts to achieve a good time on a map. + +During the run the game also displays additional info such as your current +speed, times at checkpoints etc. + +~~~ CONTROLS ~~~ + +Controls are extremely simple. The car is only controlled by 4 directional +keys: up (accelerate), down (deccelerate, reverse), left (steer left) and +right (steer right). There are two additional keys, A and B (depending on your +platform these may be e.g. the K and L letter or RETURN and SPACE keys), for +restarting runs and handling menu. + +PRO TIP: pressing brake while in air stops the car's horizontal rotation! + +~~~ DATA FILE ~~~ + +The game uses so called data file to store data such as maps and replays (if the +platform allows it). The file is usually located in the same directory as the +game and is called just "data". It's a single text file, so it can be opened in +any plain text editor. If you just want to casually play the game, you may +safely ignore the file. You will need to edit the file if you want to add new +maps and replays, or if you want to share your replays and maps with others. + +The file consists of data items -- an item represents a map, replay, and +possibly other types of data. The items are separated by the '#' (hash) +character. Each item is stored in plaintext format, there are no binary data. +Each item starts with a magic number, which is a single character ('M' for a +map, 'R' for a replay), then its name follows immediately, terminated by the +';' (semicolon) character, and then the item's data follow. Format of this data +depends on what data it is, so map data of course have a different format than +replay data. For example a map named "mymap" will start with "Mmymap;". + +~~~ CONFIGURATION ~~~ + +The game offers a very high level of configuration and customization. Very basic +settings (such as turning the music off or switching between windowed and +fullscreen mode) are accessible either in the game menu, or as a commandline +flag (run the game with -h flag to see the options). All other settings, +however, are kept at the source code level and so changing them requires +recompiling the whole game from source code (which is nonetheless very simple). +All user settings, along with their descriptions, are located in the settings.h +source file. The game also comes in several precompiled versions with different +settings. + +~~~ REPLAYS ~~~ + +If your platform supports it, Licar can save and play back recorded runs as +"replays" (sometimes also called "demos"), which are just exact records of game +inputs (so that replays, unlike videos, take very little space). Replays can +also be used to spawn a ghost car to race against. + +Replays are saved in the data file. + +Whenever a map's target time is beaten, replay is automatically saved. It's also +possible to save a replay manually by opening the menu and selecting +"save replay". + +~~~ GHOSTS ~~~ + +The game supports ghost cars to race against (note that this may be unsupported +on some weaker platforms). A ghost car is created from a replay and will race +in real time against the player, without being able to collide with him. This is +very useful when attacking someone else's (or one's own) achieved time, to see +where exactly time losses against the opponent occur. + +~~~ MAKING CUSTOM MAPS ~~~ + +Maps are stored in the data file. + +Under the asset directory there is a helper file for Blender (a FOSS 3D editor) +with which a map layout can be comfortably created. But Blender is not required +for map making, you can easily draw the map layout on a grid paper for example, +or -- for simpler maps -- it may be possible to just imagine them in one's head. + +The "workflow" for making maps is roughly the following: + +1. Drawing the map (in Blender, on paper, ...). +2. Rewriting this to the map text format in the data file. The edited map should + be the very last item in the data file so that it can be quickly loaded with + the -M command line argument. +3. Testing the map in game. This is easily done by running the game with -M + argument (and possibly also other arguments, e.g. to start with free camera) + to instantly load the edited map. If something needs changing, we return to + 1. or 2. + +~~~ FAQ ~~~ diff --git a/racing.h b/racing.h index 9eab5ed..989a758 100644 --- a/racing.h +++ b/racing.h @@ -1159,7 +1159,7 @@ uint32_t LCR_racingStep(unsigned int input) /* Apply gravity like this: if all wheels are on ground, we don't apply gravity to roof. This helps prevent sliding. */ - for (i = 0; i < 5; ++i) + for (int i = 0; i < 5; ++i) if (i < 4 || (((LCR_racing.wheelCollisions | (LCR_racing.wheelCollisions >> 4)) & 0x0f) != 0x0f)) LCR_racing.carBody.joints[i].velocity[1] -= LCR_GRAVITY;