Optimize rendering
This commit is contained in:
		
							parent
							
								
									c22f17ef8c
								
							
						
					
					
						commit
						5265552c57
					
				
					 8 changed files with 117 additions and 89 deletions
				
			
		
							
								
								
									
										78
									
								
								TODO.txt
									
										
									
									
									
								
							
							
						
						
									
										78
									
								
								TODO.txt
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,7 +1,9 @@
 | 
			
		|||
fuck issue trackers :D
 | 
			
		||||
 | 
			
		||||
=========== GENERAL ==============
 | 
			
		||||
 | 
			
		||||
- make some kinda repo for world record runs?
 | 
			
		||||
- fix the ramp map again due to new physics
 | 
			
		||||
- should drifting make a sound?
 | 
			
		||||
- keyboard ghosting is an issue, particularly when initiating drift with brake
 | 
			
		||||
  (arrow keys must be used with S for braking for left drift to work) -- think
 | 
			
		||||
  about what to do about this? or leave as is?
 | 
			
		||||
| 
						 | 
				
			
			@ -11,46 +13,11 @@
 | 
			
		|||
  its velocity by a proportion of car's velocity change (this minus prev.
 | 
			
		||||
  frame), then offset car body by this. However we'll also have to transform
 | 
			
		||||
  inbetween world space and model space.
 | 
			
		||||
- Consider better input handling in SDL? Currently it just detects presses on
 | 
			
		||||
  the exact frame, so a press can be missed. But how tho?
 | 
			
		||||
- try to add distance fog?
 | 
			
		||||
- use 332 in SDL with potato?
 | 
			
		||||
- option to turn on simple 332 colors?
 | 
			
		||||
- c99 may impose limit 4095 chars on str literal, gives warning on internal
 | 
			
		||||
  data file, try to somehow hack around it (maybe just convert it to an array in
 | 
			
		||||
  the end?) Maybe this: make a standalone C file with the string in it that
 | 
			
		||||
  when compiled and run outputs the array.
 | 
			
		||||
- culling is very slow now, it showed that distance bailout can accelerate it
 | 
			
		||||
  a lot, try to make a more accurate bailaout and see if it's faster (watch
 | 
			
		||||
  out for bugs due to false positives)
 | 
			
		||||
- maps to make:
 | 
			
		||||
  - there should be these maps:
 | 
			
		||||
    - compiled in:
 | 
			
		||||
      - standard maps, let's say 5?
 | 
			
		||||
      - additionally a few (5?) extremely simple maps, compile time option to
 | 
			
		||||
        only include these, for very weak devices with limited block/triangle
 | 
			
		||||
        count
 | 
			
		||||
    - bonus maps in the external file (also 5?)
 | 
			
		||||
  - map types:
 | 
			
		||||
    - purely falling map                                      DONE
 | 
			
		||||
    - traveling salesman kind of maze, with fans n shit       KINDA DONE
 | 
			
		||||
    - city map?                                               DONE
 | 
			
		||||
    - some kinda buggy bumpy downhill                         DONE
 | 
			
		||||
    - map where car starts upside down                        DONE
 | 
			
		||||
    - dirt map                                                DONE
 | 
			
		||||
    - ice map
 | 
			
		||||
    - boss map                                                DONE
 | 
			
		||||
    - text or picture from blocks?                            DONE
 | 
			
		||||
    - chessboard from different materials                     KINDA DONE
 | 
			
		||||
    - falling tube map?                                       DONE
 | 
			
		||||
    - grass hills as decoration?                              DONE
 | 
			
		||||
    - something with multiple roads                           DONE
 | 
			
		||||
    - RPG kinda map? could be in bonus maps                   KINDA DONE
 | 
			
		||||
    - some speed map (mostly flat to prevent high speed bugs) DONE
 | 
			
		||||
    - some (at least partially) interior map                  KINDA DONE
 | 
			
		||||
    - something with multiple finishes                        DONE
 | 
			
		||||
    - U-ramp to build speed and jump up to catch a CP (done)  DONE
 | 
			
		||||
    - jump through air ring with CP                           DONE
 | 
			
		||||
- replay validation?
 | 
			
		||||
- final tests:
 | 
			
		||||
  - very long replay
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +33,8 @@
 | 
			
		|||
  - correct saving or replays etc
 | 
			
		||||
  - empty and large data file
 | 
			
		||||
  - FPS on each platform
 | 
			
		||||
  - try to use the racing module by itself
 | 
			
		||||
  - doxygen documentation
 | 
			
		||||
 | 
			
		||||
=========== BUGS =================
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +47,16 @@
 | 
			
		|||
 | 
			
		||||
=========== HANDLED ==============
 | 
			
		||||
 | 
			
		||||
- should drifting make a sound? NO NEED
 | 
			
		||||
- Consider better input handling in SDL? Currently it just detects presses on
 | 
			
		||||
  the exact frame, so a press can be missed. But how tho? LOOKS FINE, it's
 | 
			
		||||
  only an issue with extremely low FPS, at which point it's unplayable anyway
 | 
			
		||||
- use 332 in SDL with potato?
 | 
			
		||||
- option to turn on simple 332 colors?
 | 
			
		||||
- MAP4: one triangle in top section is missing!
 | 
			
		||||
- culling is very slow now, it showed that distance bailout can accelerate it
 | 
			
		||||
  a lot, try to make a more accurate bailaout and see if it's faster (watch
 | 
			
		||||
  out for bugs due to false positives) PROLLY FINE
 | 
			
		||||
- when non-rotating, the car is very fast, allowing uberbugs: find out why and
 | 
			
		||||
  fix
 | 
			
		||||
- allow slowing down in air like in TM?
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +231,34 @@
 | 
			
		|||
- camera behavior? what if car is riding upside down (on magnet) etc? <- looks cool now
 | 
			
		||||
- allow car to be flipped upside down on start? with start block transform
 | 
			
		||||
- track size: 64x64x64
 | 
			
		||||
- maps to make:
 | 
			
		||||
  - there should be these maps:
 | 
			
		||||
    - compiled in:
 | 
			
		||||
      - standard maps, let's say 5?
 | 
			
		||||
      - additionally a few (5?) extremely simple maps, compile time option to
 | 
			
		||||
        only include these, for very weak devices with limited block/triangle
 | 
			
		||||
        count
 | 
			
		||||
    - bonus maps in the external file (also 5?)
 | 
			
		||||
  - map types:
 | 
			
		||||
    - purely falling map                                      DONE
 | 
			
		||||
    - traveling salesman kind of maze, with fans n shit       KINDA DONE
 | 
			
		||||
    - city map?                                               DONE
 | 
			
		||||
    - some kinda buggy bumpy downhill                         DONE
 | 
			
		||||
    - map where car starts upside down                        DONE
 | 
			
		||||
    - dirt map                                                DONE
 | 
			
		||||
    - ice map
 | 
			
		||||
    - boss map                                                DONE
 | 
			
		||||
    - text or picture from blocks?                            DONE
 | 
			
		||||
    - chessboard from different materials                     KINDA DONE
 | 
			
		||||
    - falling tube map?                                       DONE
 | 
			
		||||
    - grass hills as decoration?                              DONE
 | 
			
		||||
    - something with multiple roads                           DONE
 | 
			
		||||
    - RPG kinda map? could be in bonus maps                   KINDA DONE
 | 
			
		||||
    - some speed map (mostly flat to prevent high speed bugs) DONE
 | 
			
		||||
    - some (at least partially) interior map                  KINDA DONE
 | 
			
		||||
    - something with multiple finishes                        DONE
 | 
			
		||||
    - U-ramp to build speed and jump up to catch a CP (done)  DONE
 | 
			
		||||
    - jump through air ring with CP                           DONE
 | 
			
		||||
- sky images could be just composed of 4x4 normal images? then we only need
 | 
			
		||||
  one type of image
 | 
			
		||||
TOTAL SIZE OF TEXTURES:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								assets.h
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								assets.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -448,7 +448,7 @@ static const char *LCR_internalDataFile =
 | 
			
		|||
  ":^D1bJ:f11i:^J1bL:f11i"
 | 
			
		||||
  ":^D0bJ-:f11i:^J0bL-:f11i"
 | 
			
		||||
  ":^E1s:f511"
 | 
			
		||||
  ":>E0k:f513"
 | 
			
		||||
  ":>E0k:f514"
 | 
			
		||||
  // slope:
 | 
			
		||||
  ":^C2vI-:f611"
 | 
			
		||||
  ":^p3v:fj11"
 | 
			
		||||
| 
						 | 
				
			
			@ -7066,9 +7066,9 @@ void LCR_imageChangeBrightness(int up)
 | 
			
		|||
  Samples currently loaded image at given pixels coordinates (with wrapping).
 | 
			
		||||
  This is slower than reading the image pixel by pixel.
 | 
			
		||||
*/
 | 
			
		||||
uint16_t LCR_sampleImage(int x, int y)
 | 
			
		||||
uint16_t LCR_sampleImage(int_fast32_t x, int_fast32_t y)
 | 
			
		||||
{
 | 
			
		||||
  // TODO: bottleneck, later on optimize here
 | 
			
		||||
  // bottleneck here, optimization will increase rendering performance
 | 
			
		||||
  x = (y % LCR_IMAGE_SIZE) * LCR_IMAGE_SIZE + (x % LCR_IMAGE_SIZE);
 | 
			
		||||
  x += (x < 0) * (LCR_IMAGE_SIZE * LCR_IMAGE_SIZE);
 | 
			
		||||
  return LCR_currentImage.palette[LCR_currentImage.image[x]];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										5
									
								
								data
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								data
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -151,3 +151,8 @@ details
 | 
			
		|||
#BLCbonus2;
 | 
			
		||||
#RLCtiny2;00LCtiny2;833ee4b2 0000262:0014:0a10:0031:00d0:0074
 | 
			
		||||
#RLCtiny4;00LCtiny4;1787f12a 0000233:0121:0083:0091:0073:0061:0043:0031:0033:0041:0033:0061:00a3:0142:01b1:0129:0061:0159:0031:00f9:0051
 | 
			
		||||
#RLCtiny1;00LCtiny1;ae1ab677 0000327:0011:0159:0031:00d3:0041:0039:0051:0113:0021:0099:0041:0129:00d1:0153:0041:0073:0051:0043:0041:0023:0071:0023:0021:0055:0031:0013:00c1:0033:01a1:00c9:0031:01a5:0031:01b3:0041:00e9:0031:0043:0041:0049
 | 
			
		||||
#RLC1;00LC1;8bd6e314 0000566:0011:0169:0031:0109:0081:0039:0051:0039:0051:0039:0051:00b9:0011:0069:0031:0119:0091:0025:0041:0083:0132:0033:0361:00d9:0101:00d9:0081:0269:0021:00a9:0021:01a5:0031:01f3:0031:0103:0031:0023:00b1:0033:00c1:0023:0071:0063:0021:0053:0071:0189:0021
 | 
			
		||||
#BLC1;
 | 
			
		||||
#RLC1;00LC1;8bd6e314 0000527:0011:0149:0041:0039:0031:00b9:0031:0079:00a1:02d9:0081:0035:0031:0049:0271:0073:00a1:0043:0041:0099:0061:00a9:0091:0119:0031:0063:0041:0079:0031:0145:0041:0053:0171:00d3:0041:0083:0041:0043:00e1:0023:00a1:01c9:0081:0083:0051:0099:0011:0399:0031:00f3:0031:0069:0031
 | 
			
		||||
#RLC1;00LC1;8bd6e314 0000523:0011:0139:0031:0159:00a1:0049:0031:00a9:0061:0089:0041:0049:0021:0119:0071:0025:0031:0039:01e1:0043:00a1:0059:0031:0073:0021:0049:0061:0059:0041:0043:01e1:0089:0061:00b9:0021:00d9:0021:0453:0141:00b3:0091:0119:0031:00c9:0041:03b9:0021:0093:0031:00f9:0021:0039:0021
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
#define DATA_FILE_NAME "data"
 | 
			
		||||
#define LCR_LOADING_COMMAND SDL_PumpEvents();
 | 
			
		||||
 | 
			
		||||
// #define LCR_FPS_GET_MS SDL_GetTicks() // uncomment for FPS measuring
 | 
			
		||||
#define LCR_FPS_GET_MS SDL_GetTicks() // uncomment for FPS measuring
 | 
			
		||||
 | 
			
		||||
#include "game.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								game.h
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								game.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1076,10 +1076,8 @@ void LCR_gameInit(int argc, const char **argv)
 | 
			
		|||
        case 'R': quickLoad = 2; break;
 | 
			
		||||
        case 'P': quickLoad = 3; break;
 | 
			
		||||
 | 
			
		||||
        // TODO
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          LCR_LOG2("unknown argument"); 
 | 
			
		||||
          LCR_LOG1("unknown argument"); 
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -1199,7 +1197,7 @@ void LCR_gameTimeToStr(uint32_t timeMS, char *str)
 | 
			
		|||
void LCR_gameDrawPopupMessage(void)
 | 
			
		||||
{
 | 
			
		||||
#define _TEXT_SIZE 5
 | 
			
		||||
#define _OFFSET_V (LCR_EFFECTIVE_RESOLUTION_Y / 6)
 | 
			
		||||
#define _OFFSET_V (LCR_EFFECTIVE_RESOLUTION_Y / 8)
 | 
			
		||||
 | 
			
		||||
  int textH = LCR_rendererComputeTextHeight(_TEXT_SIZE);
 | 
			
		||||
  int textW = LCR_rendererComputeTextWidth(LCR_game.popupStr,_TEXT_SIZE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,29 +2,30 @@ WORK IN PROGRESS
 | 
			
		|||
 | 
			
		||||
'-._-'"'-_.-'"'-._.-'"'-._.-'"'- LICAR MANUAL -'"'-._.-'"'-._.-'"'-._.-'"'-._.-'
 | 
			
		||||
 | 
			
		||||
  libre racing video game by drummyfish
 | 
			
		||||
  libre racing video game by drummyfish (drummyfish@disroot.org)
 | 
			
		||||
  released under CC0 1.0, public domain
 | 
			
		||||
 | 
			
		||||
~~~~~ GENERAL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Licar is a relatively simple 3D stunt racing game inspired by other popular
 | 
			
		||||
games of the genre, such as Trackmania and Stunts. Unlike mainstream video
 | 
			
		||||
games, Licar is completely libre, i.e. free as in freedom (meaning its source
 | 
			
		||||
code and art assets are available for any use whatsoever), gratis (free of cost)
 | 
			
		||||
and its focus lies in being well programmed by adhering to minimalism and
 | 
			
		||||
rejecting harmful "modern" programming practices. The game aims to seflessly
 | 
			
		||||
bring joy and entertainment to all the people that might enjoy it, even those
 | 
			
		||||
who aren't able or willing to pay and/or watch ads, those owning very old and
 | 
			
		||||
weak computers and so on. It was made in whole by a single man as a completely
 | 
			
		||||
non-commercial product, the development was driven purely by love of the craft
 | 
			
		||||
and other living beings. Licar is also more than a game, for example it may
 | 
			
		||||
serve educational purposes or become a basis for new projects.
 | 
			
		||||
Licar is a relatively simple 3D stunt racing video game inspired by other
 | 
			
		||||
popular games of the genre, such as Trackmania and Stunts. Unlike mainstream
 | 
			
		||||
video games (even idie ones), Licar is completely libre, i.e. free as in freedom
 | 
			
		||||
(meaning its source code and art assets are available for any use whatsoever),
 | 
			
		||||
gratis (free of cost) and its focus lies in being well programmed by adhering to
 | 
			
		||||
minimalism and rejecting harmful "modern" programming practices. The game aims
 | 
			
		||||
to seflessly bring joy and entertainment to all the people that might enjoy it,
 | 
			
		||||
even those who aren't able or willing to pay and/or watch ads, those owning very
 | 
			
		||||
old and weak computers and so on. It was made in whole by a single man as a
 | 
			
		||||
completely non-commercial program, the development was driven purely by love of
 | 
			
		||||
the craft and other living beings to whom it might serve. Licar is also more
 | 
			
		||||
than a game, for example it may serve educational purposes or become a basis for
 | 
			
		||||
new projects.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
game, it's probably because of limitations of your platform. On PCs and laptops,
 | 
			
		||||
however, everything should be supported.
 | 
			
		||||
 | 
			
		||||
~~~~~ RUNNING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -304,13 +305,18 @@ frustration but unless you want to fix this yourself, you'll have to just accept
 | 
			
		|||
it, the game is meant to be a simple entertainment. In other words this is a
 | 
			
		||||
feature :)
 | 
			
		||||
 | 
			
		||||
Q: I found a bug or have some other important comment.
 | 
			
		||||
A: Send me an email (found on top of this file).
 | 
			
		||||
 | 
			
		||||
Q: I have some other question (such as "Why is this not written in a modern
 | 
			
		||||
language?" or "What inspired you to make the game?" etc.)
 | 
			
		||||
 | 
			
		||||
A: Many questions I often get asked about my life philosophy and opinions can't
 | 
			
		||||
now be answered shortly. I have a website at http://www.tastyfish.cz. If you
 | 
			
		||||
don't find the answer there, my email is currently drummyfish@disroot.org, feel
 | 
			
		||||
free to ask me anything, but please remember I am not very social and don't
 | 
			
		||||
enjoy too much engaging in smalltalk or lengthy discussions about worldviews
 | 
			
		||||
etcetc.
 | 
			
		||||
A: Many questions I often get asked about my life and/or programming philosophy
 | 
			
		||||
can't now be answered in a tl;dr way without doing them injustice. I have a
 | 
			
		||||
website at http://www.tastyfish.cz, where I attempt to explain things, but
 | 
			
		||||
please note you will probably not like it. If you still decide to follow the
 | 
			
		||||
link and don't find your answer, feel to ask me anything over email, but please
 | 
			
		||||
remember I am not very social and don't enjoy too much engaging in smalltalk or
 | 
			
		||||
lengthy discussions about worldviews etcetc. I am certainly not interested in
 | 
			
		||||
having my opinions changed or changing someone else's mind by force.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										31
									
								
								racing.h
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								racing.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,10 +6,15 @@
 | 
			
		|||
  Licar: racing module
 | 
			
		||||
  
 | 
			
		||||
  This implements the racing physics and logic as well as replays and other
 | 
			
		||||
  related things. It's possible to use this module alone if one wants to
 | 
			
		||||
  related stuff. It's possible to use this module alone if one wants to
 | 
			
		||||
  implement a program that doesn't need graphics, I/O etc.
 | 
			
		||||
 | 
			
		||||
  Some comments:
 | 
			
		||||
  - This module uses tinyphysicsengine, a small and simple physics engine that
 | 
			
		||||
    uses "balls and springs" to model bodies (here the car) and kind of
 | 
			
		||||
    "signed distance functions" to model environment (the map). The car is
 | 
			
		||||
    strictly a soft body, but it's very "stiff" so that it behaves almost like
 | 
			
		||||
    a rigid body.
 | 
			
		||||
  - Replays are internally stored as follows: the replay consists of 16 bit
 | 
			
		||||
    words representing changes in input at specific frame. In lowest 4 bits the
 | 
			
		||||
    new input state is recorded, the remaining 12 bits record physics frame
 | 
			
		||||
| 
						 | 
				
			
			@ -91,8 +96,6 @@ typedef int32_t LCR_GameUnit;        ///< abstract game unit
 | 
			
		|||
#define LCR_CAR_GRASS_FACTOR 5
 | 
			
		||||
#define LCR_CAR_DIRT_FACTOR  3
 | 
			
		||||
#define LCR_CAR_ICE_FACTOR   1
 | 
			
		||||
//#define LCR_CAR_DRIFT_FACTOR 2    ///< only affects steering friction
 | 
			
		||||
 | 
			
		||||
#define LCR_CAR_DRIFT_FACTOR 2    ///< only affects steering friction
 | 
			
		||||
 | 
			
		||||
#define LCR_CAR_DRIFT_THRESHOLD_1 (LCR_GAME_UNIT / 10)
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +221,6 @@ void LCR_replayOutputStr(void (*printChar)(char))
 | 
			
		|||
 | 
			
		||||
#define PUTD(order) \
 | 
			
		||||
  printChar('0' + (LCR_racing.replay.achievedTime / order) % 10);
 | 
			
		||||
 | 
			
		||||
  PUTD(1000000) PUTD(100000) PUTD(10000)
 | 
			
		||||
  PUTD(1000) PUTD(100) PUTD(10) PUTD(1)
 | 
			
		||||
#undef PUTD
 | 
			
		||||
| 
						 | 
				
			
			@ -252,7 +254,7 @@ int LCR_replayLoadFromStr(char (*nextChar)(void),
 | 
			
		|||
  LCR_racing.replay.eventCount = 0;
 | 
			
		||||
  LCR_racing.replay.achievedTime = 0;
 | 
			
		||||
 | 
			
		||||
  // has to be like this to force correct evaluation order:
 | 
			
		||||
  // Has to be like this to force correct evaluation order:
 | 
			
		||||
  c = nextChar() == LCR_RACING_VERSION1;
 | 
			
		||||
  c |= (nextChar() == LCR_RACING_VERSION2) << 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -431,8 +433,10 @@ int LCR_replayRecordEvent(uint32_t frame, uint8_t input)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Helper function for _LCR_racingEnvironmentFunction, returns closest point on
 | 
			
		||||
  a map block placed at coordinate origin.
 | 
			
		||||
  Helper function for _LCR_racingEnvironmentFunction, for given arbitrary point
 | 
			
		||||
  returns the closest point on map block (of given type) placed at coordinate
 | 
			
		||||
  origin (and in default orientation). This function defines shapes of map
 | 
			
		||||
  blocks.
 | 
			
		||||
*/
 | 
			
		||||
TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -758,7 +762,7 @@ TPE_Vec3 _LCR_racingBlockEnvFunc(TPE_Vec3 point, const uint8_t *block)
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
  For tinyphysicsengine, function that defines the shape of the static physics
 | 
			
		||||
  world, returns closest point to any given point in space.
 | 
			
		||||
  world. For any given point in space returns the environment's closest point.
 | 
			
		||||
*/
 | 
			
		||||
TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -821,7 +825,7 @@ TPE_Vec3 _LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
 | 
			
		|||
        TPE_ENV_NEXT(_LCR_racingBlockEnvFunc(point, // check it
 | 
			
		||||
          LCR_currentMap.blocks + blockNum * LCR_BLOCK_SIZE),point)
 | 
			
		||||
 | 
			
		||||
        // narrow the search range:
 | 
			
		||||
        // Narrow the search range:
 | 
			
		||||
        if (i % 2 == 0 && blockNum > start)
 | 
			
		||||
          start = blockNum;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -869,8 +873,7 @@ uint8_t _LCR_racingCollisionHandler(uint16_t b1, uint16_t j1, uint16_t b2,
 | 
			
		|||
      LCR_racing.carBody.joints[j1].velocity[0],
 | 
			
		||||
        LCR_racing.carBody.joints[j1].velocity[1],
 | 
			
		||||
        LCR_racing.carBody.joints[j1].velocity[2]),
 | 
			
		||||
      TPE_vec3Minus(p,
 | 
			
		||||
        LCR_racing.carBody.joints[j1].position)));
 | 
			
		||||
      TPE_vec3Minus(p,LCR_racing.carBody.joints[j1].position)));
 | 
			
		||||
 | 
			
		||||
  LCR_racing.crashState |= ((speed >= LCR_CAR_CRASH_SPEED_BIG) << 1) |
 | 
			
		||||
    (speed >= LCR_CAR_CRASH_SPEED_SMALL);
 | 
			
		||||
| 
						 | 
				
			
			@ -1527,10 +1530,10 @@ uint32_t LCR_racingStep(unsigned int input)
 | 
			
		|||
  {
 | 
			
		||||
    LCR_LOG2("roof squeezed, applying anti force")
 | 
			
		||||
 | 
			
		||||
    TPE_Vec3 tmpVec = TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 16); // TODO: 16 magic con.
 | 
			
		||||
    TPE_Vec3 tmpVec =
 | 
			
		||||
      TPE_vec3Times(carUp,LCR_PHYSICS_UNIT / 16); // 16: magic const.
 | 
			
		||||
 | 
			
		||||
    angle = TPE_F - 4 * angle; // 4 comes from above TPE_F / 4
 | 
			
		||||
 | 
			
		||||
    tmpVec = TPE_vec3Times(tmpVec,angle);
 | 
			
		||||
 | 
			
		||||
    if (angle <= 0)  
 | 
			
		||||
| 
						 | 
				
			
			@ -1540,7 +1543,7 @@ uint32_t LCR_racingStep(unsigned int input)
 | 
			
		|||
      angle = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // accelerate roof and wheels away from each other
 | 
			
		||||
    // Accelerate roof and wheels away from each other:
 | 
			
		||||
    for (int i = 0; i < LCR_CAR_JOINTS; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      LCR_racing.carBody.joints[i].velocity[0] += (i == 4 ? 1 : -1) * tmpVec.x;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								renderer.h
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								renderer.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -10,6 +10,9 @@
 | 
			
		|||
 | 
			
		||||
  Some comments:
 | 
			
		||||
 | 
			
		||||
  - The module uses small3dlib, a tiny software rasterization library. This
 | 
			
		||||
    module knows nothing about I/O (windows, canvases, ...), it just say where
 | 
			
		||||
    to draw pixels and what colors they should have.
 | 
			
		||||
  - The map 3D model is divided into 4x4x4 chunks, i.e. 64 in total, out of
 | 
			
		||||
    which only 8 are loaded at any time, depending on where the camera is and
 | 
			
		||||
    where it is looking. This is to save resources, we don't draw the far away
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +20,10 @@
 | 
			
		|||
  - Extremely simple LOD of far away chunks is implemented: we keep an 8x8x8
 | 
			
		||||
    bit array of where there is empty space and where there is "something", then
 | 
			
		||||
    for far away areas with "something" we just draw some 2D rectangles.
 | 
			
		||||
  - RENDERING IS THE BOTTLENECK OF PERFORMANCE, it takes even much more time
 | 
			
		||||
    than physics simulation, i.e. care should be taken to make code here very
 | 
			
		||||
    optimized, namely the _LCR_pixelFunc3D function, as it is called for every
 | 
			
		||||
    rasterized pixel.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define S3L_RESOLUTION_X LCR_EFFECTIVE_RESOLUTION_X
 | 
			
		||||
| 
						 | 
				
			
			@ -108,12 +115,12 @@ struct
 | 
			
		|||
  // pixel function precomputed values:
 | 
			
		||||
  uint32_t previousTriID;
 | 
			
		||||
  int triUVs[6];
 | 
			
		||||
  int texSubsampleCount;
 | 
			
		||||
  unsigned int flatAndTransparent; /**< If non-zero, transparent (dithered)
 | 
			
		||||
                                        polygons will be drawn without texture,
 | 
			
		||||
                                        with color stored in this variable. */
 | 
			
		||||
  uint_fast16_t texSubsampleCount;
 | 
			
		||||
  uint_fast16_t flatAndTransparent; /**< If non-zero, transparent (dithered)
 | 
			
		||||
                                         polygons will be drawn without texture,
 | 
			
		||||
                                         with color stored in this variable. */
 | 
			
		||||
#if LCR_SETTING_PARTICLES
 | 
			
		||||
  uint16_t particleColor;          /**< 0x0000 means no particles active. */
 | 
			
		||||
  uint_fast16_t particleColor;      /**< 0x0000 means no particles active. */
 | 
			
		||||
#endif
 | 
			
		||||
} LCR_renderer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -338,7 +345,7 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
 | 
			
		|||
  LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
 | 
			
		||||
 | 
			
		||||
#else // LCR_SETTING_POTATO_GRAPHICS
 | 
			
		||||
  // once we get a new triangle, we precompute things for it:
 | 
			
		||||
  // New triangle? Precompute stuff for it:
 | 
			
		||||
  if (pixel->triangleID != LCR_renderer.previousTriID)
 | 
			
		||||
  {
 | 
			
		||||
    LCR_renderer.previousTriID = pixel->triangleID;
 | 
			
		||||
| 
						 | 
				
			
			@ -483,10 +490,14 @@ void _LCR_pixelFunc3D(S3L_PixelInfo *pixel)
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Bottleneck: code from here below will be ran for every rasterized pixel,
 | 
			
		||||
     optimizing it may significantly improve rendering performance. */
 | 
			
		||||
 | 
			
		||||
  if (LCR_renderer.flatAndTransparent)
 | 
			
		||||
  {
 | 
			
		||||
    if (pixel->x % 2 == pixel->y % 2)
 | 
			
		||||
      LCR_gameDrawPixelXYUnsafe(pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
 | 
			
		||||
    if ((pixel->x % 2) == (pixel->y % 2))
 | 
			
		||||
      LCR_gameDrawPixelXYUnsafe(
 | 
			
		||||
        pixel->x,pixel->y,LCR_renderer.flatAndTransparent);
 | 
			
		||||
    else
 | 
			
		||||
      S3L_zBufferWrite(pixel->x,pixel->y,S3L_MAX_DEPTH);
 | 
			
		||||
      /* ^ Clear z-buffer if we didn't draw the pixel. Without this further
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,8 +1045,7 @@ uint8_t _LCR_buildMapModel(void)
 | 
			
		|||
                LCR_IMAGE_WALL_CONCRETE : LCR_IMAGE_WALL_WOOD;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            { // TODO: tidy this mess?
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
              if (LCR_mapBlockIsAccelerator(blockType))
 | 
			
		||||
                triData |= LCR_IMAGE_GROUND_ACCEL;
 | 
			
		||||
              else if (LCR_mapBlockIsFan(blockType))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue