Add sound

This commit is contained in:
Miloslav Ciz 2025-01-29 16:27:47 +01:00
parent be11c582b1
commit 67e0814afb
8 changed files with 124 additions and 94 deletions

View file

@ -1,12 +1,13 @@
#ifndef _LCR_ASSETS_H
#define _LCR_ASSETS_H
/*
/** @file assets.h
Licar: assets
This file holds assets, resources and other bigger pieces of data that will be
compiled right into the executable. This is so that for a minimal version of
the game a filesystem is not needed.
This file holds assets, resources and other bigger pieces of data that are to
be compiled right into the executable. This is so that for a minimal version
of the game a filesystem is not required.
NOTES:
- All images are 64x64, stored in an indexed mode (8bits pery pixel), the
@ -103,23 +104,23 @@ struct
const uint8_t *image;
} LCR_currentImage;
/*
Font characters are kind of "segmented display" characters, encoded with 16
bits (each for one segment) like this (numbered from LSB):
__0__ __2__
|\12 |\13 |
1| \ 5| \ 9|
| \ | \ |
|__4\_|__6\_|
|\14 |\15 |
3| \ 7| \ 11|
| \ | \ |
|__8\_|_10\_|
*/
uint16_t LCR_getFontChar(char c)
{
/*
Font consists of kind of "segmented display" characters, encoded with 16
bits (each for one segment) like this (numbered from LSB):
__0__ __2__
|\12 |\13 |
1| \ 5| \ 9|
| \ | \ |
|__4\_|__6\_|
|\14 |\15 |
3| \ 7| \ 11|
| \ | \ |
|__8\_|_10\_|
*/
#define _F(a,b,c,d,e,f,g,h,i,j) return (1 << a) | (1 << b) | (1 << c) | (1 <<\
d) | (1 << e) | (1 << f) | (1 << g) | (1 << h) | (1 << i) | (1 << j); break;

31
audio.h
View file

@ -1,4 +1,8 @@
/*
#ifndef _LCR_AUDIO
#define _LCR_AUDIO
/** @file audio.h
Licar audio
This file implements the audio system. The module only computes audio samples
@ -7,9 +11,6 @@
file, left to be optionally loaded and played by the frontend).
*/
#ifndef _LCR_AUDIO
#define _LCR_AUDIO
#define LCR_SOUND_NONE 0
#define LCR_SOUND_CLICK 1
#define LCR_SOUND_CRASH_SMALL 2
@ -58,7 +59,7 @@ void LCR_audioSetEngineIntensity(uint8_t value)
}
/**
Tells the audio system to play certain sound (see the sound constants).
Tells the audio system to play a certain sound (see the sound constants).
*/
void LCR_audioPlaySound(uint8_t sound)
{
@ -67,6 +68,16 @@ void LCR_audioPlaySound(uint8_t sound)
LCR_audio.soundPlayedFrame = 0;
}
/**
Same as LCR_audioPlaySound, but only plays the sound if no other sound is
playing.
*/
void LCR_audioPlaySoundIfFree(uint8_t sound)
{
if (LCR_audio.soundPlayed == LCR_SOUND_NONE)
LCR_audioPlaySound(sound);
}
uint8_t _LCR_audioNoise(void)
{
LCR_audio.noise = LCR_audio.noise * 32310901 + 37;
@ -106,6 +117,16 @@ uint8_t LCR_audioGetNextSample(void)
break;
}
case LCR_SOUND_ACCELERATOR:
result = putchar(((LCR_audio.soundPlayedFrame * 14 +
(((LCR_audio.soundPlayedFrame >> 2) * (LCR_audio.soundPlayedFrame >> 6))
>> 4)) & 0x0f));
if (LCR_audio.soundPlayedFrame >= 4000)
LCR_audio.soundPlayed = LCR_SOUND_NONE;
break;
case LCR_SOUND_CLICK:
{
int v = ((LCR_audio.soundPlayedFrame >> 6) *

5
game.h
View file

@ -1,7 +1,8 @@
#ifndef _LCR_GAME_H
#define _LCR_GAME_H
/*
/** @file game.h
Licar: game module
This file implements the backend of a complete, actually playable game with
@ -1385,6 +1386,8 @@ LCR_replayOutputStr(_LCR_gameDataCharWrite);
LCR_audioPlaySound(LCR_SOUND_CRASH_BIG);
LCR_LOG2("crash (big)");
}
else if (events & LCR_RACING_EVENT_ACCELERATOR)
LCR_audioPlaySoundIfFree(LCR_SOUND_ACCELERATOR);
int engineIntensity = LCR_carSpeedKMH() * 2;

View file

@ -1,7 +1,8 @@
#ifndef _LCR_GENERAL_H
#define _LCR_GENERAL_H
/*
/** @file general.h
Licar: general
This file holds general definitions used by all modules.

121
map.h
View file

@ -1,7 +1,8 @@
#ifndef _LCR_MAP
#define _LCR_MAP
/*
/** @file map.h
Licar: map module
This implements maps (i.e. tracks, levels, ...).
@ -58,31 +59,29 @@
#include "general.h"
#define LCR_MAP_NAME_MAX_LEN 15 /**< Maximum map name length (without
terminating zero. */
#define LCR_BLOCK_START_CHAR ':'
#define LCR_MAP_NAME_MAX_LEN 15 /**< Maximum map name length (without
terminating zero. */
#define LCR_BLOCK_START_CHAR ':'
/** Maximum number of triangles of a block shape. */
#define LCR_MAP_BLOCK_SHAPE_MAX_BYTES 80
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
#define LCR_BLOCK_TRANSFORM_ROT_90 0x20
#define LCR_BLOCK_TRANSFORM_ROT_180 0x40
#define LCR_BLOCK_TRANSFORM_ROT_270 0x60
#define LCR_BLOCK_TRANSFORM_FLIP_V 0x80
#define LCR_BLOCK_TRANSFORM_FLIP_H 0x10
#define LCR_BLOCK_TRANSFORM_ROT_90 0x20
#define LCR_BLOCK_TRANSFORM_ROT_180 0x40
#define LCR_BLOCK_TRANSFORM_ROT_270 0x60
#define LCR_BLOCK_TRANSFORM_FLIP_V 0x80
#define LCR_BLOCK_XYZ_TO_COORD(x,y,z) // ???
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(uint8_t) (x | (y << 6)), \
(uint8_t) ((y >> 2) | (z << 4)), \
(uint8_t) ((z >> 4) | (m << 2) | (r))
#define LCR_MAP_BLOCK(t,x,y,z,m,r) t,(uint8_t) (x | (y << 6)), \
(uint8_t) ((y >> 2) | (z << 4)), \
(uint8_t) ((z >> 4) | (m << 2) | (r))
#define LCR_BLOCK_SIZE 4 ///< size of map block, in bytes
#define LCR_BLOCK_SIZE 4 ///< size of map block, in bytes
#define LCR_BLOCK_MATERIAL_CONCRETE 0x00
#define LCR_BLOCK_MATERIAL_GRASS 0x01
#define LCR_BLOCK_MATERIAL_DIRT 0x02
#define LCR_BLOCK_MATERIAL_ICE 0x03
#define LCR_BLOCK_MATERIAL_CONCRETE 0x00
#define LCR_BLOCK_MATERIAL_GRASS 0x01
#define LCR_BLOCK_MATERIAL_DIRT 0x02
#define LCR_BLOCK_MATERIAL_ICE 0x03
// normal blocks:
#define LCR_BLOCK_FULL '=' ///< completely filled block
@ -97,7 +96,7 @@
#define LCR_BLOCK_RAMP_14 '_' ///< plain ramp, 1/4 size
#define LCR_BLOCK_RAMP_12_UP '\'' ///< ramp, 1/2 size, elevated up
#define LCR_BLOCK_RAMP_CORNER 'v' ///< corner of a ramp
#define LCR_BLOCK_RAMP_CURVED_PLAT ']' ///< curved ramp with top platgform
#define LCR_BLOCK_RAMP_CURVED_PLAT ']' ///< curved ramp with top platform
#define LCR_BLOCK_RAMP_CURVED ')' ///< curv. ramp without top platf.
#define LCR_BLOCK_RAMP_CURVED_WALL '}' ///< curved ramp plus small wall
#define LCR_BLOCK_RAMP_STEEP '|' ///< extremely steep ramp
@ -712,18 +711,18 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
{
uint8_t
xRight = 6 >>
(blockType == LCR_BLOCK_LEFT ||
blockType == LCR_BLOCK_BOTTOM_LEFT ||
blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT ||
blockType == LCR_BLOCK_LEFT_FRONT),
((blockType == LCR_BLOCK_LEFT) |
(blockType == LCR_BLOCK_BOTTOM_LEFT) |
(blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT) |
(blockType == LCR_BLOCK_LEFT_FRONT)),
yTop = 4 >>
(blockType == LCR_BLOCK_BOTTOM ||
blockType == LCR_BLOCK_BOTTOM_ACCEL ||
blockType == LCR_BLOCK_BOTTOM_LEFT ||
blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT),
((blockType == LCR_BLOCK_BOTTOM) |
(blockType == LCR_BLOCK_BOTTOM_ACCEL) |
(blockType == LCR_BLOCK_BOTTOM_LEFT) |
(blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT)),
zBack = 6 >>
(blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT ||
blockType == LCR_BLOCK_LEFT_FRONT);
((blockType == LCR_BLOCK_BOTTOM_LEFT_FRONT) |
(blockType == LCR_BLOCK_LEFT_FRONT));
ADD(0,0,0) ADD(xRight,0,0) ADD(xRight,yTop,0) // front
ADD(0,0,0) ADD(xRight,yTop,0) ADD(0,yTop,0)
@ -737,7 +736,6 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
ADD(0,yTop,0) ADD(xRight,yTop,zBack) ADD(0,yTop,zBack)
ADD(0,0,0) ADD(xRight,0,zBack) ADD(xRight,0,0) // bottom
ADD(0,0,0) ADD(0,0,zBack) ADD(xRight,0,zBack)
break;
}
@ -843,14 +841,14 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
{
uint8_t right = blockType == LCR_BLOCK_CORNER ? 6 : 3;
ADD(0,0,0) ADD(right,0,6) ADD(right,4,6) // front/right
ADD(0,0,0) ADD(right,0,6) ADD(right,4,6) // front/right
ADD(0,0,0) ADD(right,4,6) ADD(0,4,0)
ADD(0,0,0) ADD(0,4,6) ADD(0,0,6) // left
ADD(0,0,0) ADD(0,4,6) ADD(0,0,6) // left
ADD(0,0,0) ADD(0,4,0) ADD(0,4,6)
ADD(right,0,6) ADD(0,0,6) ADD(0,4,6) // back
ADD(right,0,6) ADD(0,0,6) ADD(0,4,6) // back
ADD(0,4,6) ADD(right,4,6) ADD(right,0,6)
ADD(0,4,0) ADD(right,4,6) ADD(0,4,6) // top
ADD(0,0,6) ADD(right,0,6) ADD(0,0,0) // bottom
ADD(0,4,0) ADD(right,4,6) ADD(0,4,6) // top
ADD(0,0,6) ADD(right,0,6) ADD(0,0,0) // bottom
break;
}
@ -862,58 +860,58 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
mx = blockType == LCR_BLOCK_CORNER_CONVEX ? 4 : 2,
mz = blockType == LCR_BLOCK_CORNER_CONVEX ? 2 : 4;
ADD(0,0,0) ADD(0,4,6) ADD(0,0,6) // left
ADD(0,0,0) ADD(0,4,0) ADD(0,4,6) // left
ADD(6,0,6) ADD(0,0,6) ADD(0,4,6) // back
ADD(0,4,6) ADD(6,4,6) ADD(6,0,6) // back
ADD(0,0,0) ADD(mx,4,mz) ADD(0,4,0) // right
ADD(0,0,0) ADD(0,4,6) ADD(0,0,6) // left
ADD(0,0,0) ADD(0,4,0) ADD(0,4,6) // left
ADD(6,0,6) ADD(0,0,6) ADD(0,4,6) // back
ADD(0,4,6) ADD(6,4,6) ADD(6,0,6) // back
ADD(0,0,0) ADD(mx,4,mz) ADD(0,4,0) // right
ADD(mx,0,mz) ADD(mx,4,mz) ADD(0,0,0)
ADD(6,4,6) ADD(mx,4,mz) ADD(6,0,6)
ADD(6,0,6) ADD(mx,4,mz) ADD(mx,0,mz)
ADD(0,4,0) ADD(mx,4,mz) ADD(0,4,6) // top
ADD(0,4,0) ADD(mx,4,mz) ADD(0,4,6) // top
ADD(0,4,6) ADD(mx,4,mz) ADD(6,4,6)
ADD(0,0,0) ADD(0,0,6) ADD(mx,0,mz) // bottom
ADD(0,0,0) ADD(0,0,6) ADD(mx,0,mz) // bottom
ADD(0,0,6) ADD(6,0,6) ADD(mx,0,mz)
break;
}
case LCR_BLOCK_BUMP:
ADD(3,0,0) ADD(6,0,3) ADD(3,1,3) // top
ADD(3,0,0) ADD(6,0,3) ADD(3,1,3) // top
ADD(6,0,3) ADD(3,0,6) ADD(3,1,3)
ADD(3,0,6) ADD(0,0,3) ADD(3,1,3)
ADD(0,0,3) ADD(3,0,0) ADD(3,1,3)
ADD(3,0,0) ADD(3,0,6) ADD(6,0,3) // bottom
ADD(3,0,6) ADD(3,0,0) ADD(0,0,3) // bottom
ADD(3,0,0) ADD(3,0,6) ADD(6,0,3) // bottom
ADD(3,0,6) ADD(3,0,0) ADD(0,0,3) // bottom
break;
case LCR_BLOCK_RAMP_CORNER:
ADD(6,0,6) ADD(0,0,0) ADD(6,4,0) // diagonal
ADD(6,0,6) ADD(6,4,0) ADD(6,0,0) // right
ADD(0,0,0) ADD(6,0,0) ADD(6,4,0) // front
ADD(0,0,0) ADD(6,0,6) ADD(6,0,0) // bottom
ADD(6,0,6) ADD(0,0,0) ADD(6,4,0) // diagonal
ADD(6,0,6) ADD(6,4,0) ADD(6,0,0) // right
ADD(0,0,0) ADD(6,0,0) ADD(6,4,0) // front
ADD(0,0,0) ADD(6,0,6) ADD(6,0,0) // bottom
break;
case LCR_BLOCK_HILL:
ADD(0,0,0) ADD(6,0,0) ADD(0,2,1) // front
ADD(0,0,0) ADD(6,0,0) ADD(0,2,1) // front
ADD(6,0,0) ADD(6,2,1) ADD(0,2,1)
ADD(0,2,1) ADD(6,2,1) ADD(0,3,2) // front 2
ADD(0,2,1) ADD(6,2,1) ADD(0,3,2) // front 2
ADD(6,2,1) ADD(6,3,2) ADD(0,3,2)
ADD(0,3,2) ADD(6,3,2) ADD(0,4,4) // front 3
ADD(0,3,2) ADD(6,3,2) ADD(0,4,4) // front 3
ADD(6,3,2) ADD(6,4,4) ADD(0,4,4)
ADD(0,4,4) ADD(6,4,4) ADD(0,4,6) // top
ADD(0,4,4) ADD(6,4,4) ADD(0,4,6) // top
ADD(6,4,4) ADD(6,4,6) ADD(0,4,6)
ADD(0,0,0) ADD(0,0,6) ADD(6,0,0) // bottom
ADD(0,0,0) ADD(0,0,6) ADD(6,0,0) // bottom
ADD(6,0,0) ADD(0,0,6) ADD(6,0,6)
ADD(0,0,6) ADD(0,4,6) ADD(6,4,6) // back
ADD(0,0,6) ADD(0,4,6) ADD(6,4,6) // back
ADD(0,0,6) ADD(6,4,6) ADD(6,0,6)
ADD(0,0,0) ADD(0,2,1) ADD(0,0,6) // left
ADD(0,0,0) ADD(0,2,1) ADD(0,0,6) // left
ADD(0,2,1) ADD(0,3,2) ADD(0,0,6)
ADD(0,3,2) ADD(0,4,4) ADD(0,0,6)
ADD(0,4,4) ADD(0,4,6) ADD(0,0,6)
ADD(6,0,0) ADD(6,0,6) ADD(6,2,1) // right
ADD(6,2,1) ADD(6,0,6) ADD(6,3,2)
ADD(6,3,2) ADD(6,0,6) ADD(6,4,4)
ADD(6,4,4) ADD(6,0,6) ADD(6,4,6)
ADD(6,0,0) ADD(6,0,6) ADD(6,2,1) // right
ADD(6,2,1) ADD(6,0,6) ADD(6,3,2)
ADD(6,3,2) ADD(6,0,6) ADD(6,4,4)
ADD(6,4,4) ADD(6,0,6) ADD(6,4,6)
break;
@ -927,7 +925,6 @@ void LCR_mapGetBlockShape(uint8_t blockType, uint8_t transform,
uint8_t x, y, z;
_LCR_decodeMapBlockCoords(bytes[i],&x,&y,&z);
LCR_TRANSFORM_COORDS(transform,x,y,z,6,4)
bytes[i] = _LCR_encodeMapBlockCoords(x,y,z);

View file

@ -1,7 +1,8 @@
#ifndef _LCR_RACING_H
#define _LCR_RACING_H
/*
/** @file racing.h
Licar: racing module
This implements the racing physics and logic as well as replays and other
@ -40,6 +41,7 @@ typedef int32_t LCR_GameUnit; ///< abstract game unit
#define LCR_RACING_EVENT_FINISHED 0x0002
#define LCR_RACING_EVENT_CRASH_SMALL 0x0004
#define LCR_RACING_EVENT_CRASH_BIG 0x0008
#define LCR_RACING_EVENT_ACCELERATOR 0x0010
#define LCR_PHYSICS_UNIT 4096 ///< len. of square for phys. engine
@ -1211,7 +1213,10 @@ uint32_t LCR_racingStep(unsigned int input)
_LCR_applyMaterialFactor(LCR_CAR_FORWARD_FRICTION,groundMat);
if (onAccel)
{
input |= LCR_RACING_INPUT_FORW; // accelerator enforces this
result |= LCR_RACING_EVENT_ACCELERATOR;
}
if(!(input & (LCR_RACING_INPUT_FORW | LCR_RACING_INPUT_BACK)))
LCR_racing.carBody.friction *= LCR_CAR_STAND_FRICTION_MULTIPLIER;
@ -1330,13 +1335,13 @@ uint32_t LCR_racingStep(unsigned int input)
if ((!LCR_racing.carDrifting) &&
driftFriction > LCR_CAR_DRIFT_THRESHOLD_1)
{
LCR_LOG1("drift start");
LCR_LOG2("drift start");
LCR_racing.carDrifting = 1;
}
else if (LCR_racing.carDrifting &&
driftFriction < LCR_CAR_DRIFT_THRESHOLD_0)
{
LCR_LOG1("drift end");
LCR_LOG2("drift end");
LCR_racing.carDrifting = 0;
}

View file

@ -1,7 +1,8 @@
#ifndef _LCR_RENDERER_H
#define _LCR_RENDERER_H
/*
/** @file renderer.h
Licar: renderer module
This implements 3D and 2D rendering. It should be possible to replace this

View file

@ -1,7 +1,8 @@
#ifndef _LCR_SETTINGS_H
#define _LCR_SETTINGS_H
/*
/** @file settings.h
Licar: settings
Compile times settings file for all modules, values here may be changed by the
@ -159,7 +160,7 @@
#ifndef LCR_SETTING_DEBUG_PHYSICS_DRAW
/** If on, physics world will be drawn. */
#define LCR_SETTING_DEBUG_PHYSICS_DRAW 1
#define LCR_SETTING_DEBUG_PHYSICS_DRAW 0
#endif
#ifndef LCR_SETTING_POTATO_GRAPHICS