If the game is from 1995, it's quite certain that the file format is specific to this game and the game studio that produced it. Game engines like Unity weren't a thing then; Studios wrote their software in C, maybe C++, and invented their own files and packers.
So, the "real" file format is what you're seeing; and the software used to create the file was very probably written specifically for this game and has since been long lost, especially if the game is abandonware which probably means the company behind it went defunct at some time. So, don't expect to be able to find any software these days that can read your files directly.
What you might be able to do is find out how the internal files are packed together and write some C/Perl/Python/... code to extract the
.SPR contents, try software like
trid if those contents are some generic format (unlikely but at least not impossible), then analyze these individual files in a hex editor to find their structure. But, as malikcjm said, it's very likely that you won't be able to read the files unless you disassemble the game binary to check how the game itself reads them, derive the file format from that, and then write some code yourself to convert that format to something modern.
If you can, you might try uploading the files somewhere and provide a link, as well as tell us which game they are from and who produced it; chances are someone who has seen similar files might recognize them.
When I download the files and compress them, the size of at least the two CITY files doesn't shrink much:
gbl@roran:~/Temp/Winrace$ ls -l
-rw-r--r-- 1 gbl users 44423 Dec 1 05:10 CITY.ENV
-rw-r--r-- 1 gbl users 242641 Dec 1 05:10 CITY1.LEV
-rw-r--r-- 1 gbl users 52720 Dec 1 05:10 MINI.VHC
-rw-r--r-- 1 gbl users 462848 Dec 1 05:10 WINRACE.EXE
gbl@roran:~/Temp/Winrace$ gzip *
gbl@roran:~/Temp/Winrace$ ls -l
-rw-r--r-- 1 gbl users 38260 Dec 1 05:10 CITY.ENV.gz
-rw-r--r-- 1 gbl users 223044 Dec 1 05:10 CITY1.LEV.gz
-rw-r--r-- 1 gbl users 26003 Dec 1 05:10 MINI.VHC.gz
-rw-r--r-- 1 gbl users 186138 Dec 1 05:10 WINRACE.EXE.gz
See how the .EXE compresses much better than the CITY* files? So it's likely those files are compressed, but with an algorithm that's a bit weaker than gzip. This would explain why you can't really find useful strings in them as well.
Now, let's check the hex dump of CITY.ENV which begins with:
00000000 43 49 54 59 2e 54 58 54 00 6b 00 00 00 a5 00 00 CITY.TXT.k......
00000010 00 03 fb 0d 0a 01 00 20 20 73 70 6f ff 74 20 31 ....... spo.t 1
00000020 20 52 55 42 42 ef 45 52 46 58 05 00 20 33 2c d7 RUBB.ERFX.. 3,.
00000030 31 37 2c 17 00 30 01 58 44 55 af 53 54 31 5f 14 17,..0.XDU.ST1_.
00000040 30 32 1d 08 35 7e 21 58 42 49 47 53 50 4c 36 08 02..5~!XBIGSPL6.
00000050 da 37 38 32 03 38 32 20 51 08 41 53 41 48 6a 00 .782.82 Q.ASAHj.
00000060 16 18 1c 10 5f 10 61 38 33 6b 08 77 41 52 4b 33 ...._.a83k.wARK3
00000070 20 36 2c 34 7a 10 03 2d 31 41 10 a2 00 43 41 52 6,4z..-1A...CAR
00000080 53 45 4c 2e 52 41 57 00 d2 6c 00 00 00 fd 00 00 SEL.RAW..l......
Obviously, there's a filename CITY.TXT at offset 0000, and another one at offset 007D. So the question is, how does the decoder know how long a file is, and where the next one starts? And how does it know how long the file name is, as they don't all have the same length?
Both of these file names end with a
\0, the string terminator in C, so let's just assume this
\0 doesn't have another meaning. Next is
0000006B in little-endian that x86 uses, which is just a bit less than the offset of the next file name. So this might have to do with the compressed length of the file.
Checking this with the next file at 007D, we find a length of 6CD2. Adding the start of the file name to this, we get 6D4D. And indeed, a few bytes behind that, at 6D63, we have
00006d60 03 dd d5 52 55 42 42 45 52 46 58 2e 46 54 00 40 ...RUBBERFX.FT.@
the next filename.
So let's make a table - byte position of filename, filename, integer after filename, sum of byte position and integer, position of next filename, and offset that needs to be added to the sum to reach the next filename:
0000 CITY.TXT 006B 006B 007D +0012
007D CARSEL.RAW 6CD2 6D4D 6D63 +0016
6D63 RUBBERFX.FT 0040 6DA3 6DB8 +0015
6DB8 RUBBERFX.3DW 045F 7217 722C +0015
722C PSPOTFX2.TM 1CBA 8EE6 8EFA +0014
8EFA FDUST1_FX.FT ..... <-- the first F might be spurious as the next file is DUST1.FX
Obviously, the assumption that these 4 bytes are the length of the compressed bytes seems to be true, even when we don't know yet why the offsets (last column) aren't constant. Doesn't seem like they have to do with the length of the filename either, as the first two differ 2 in length but 4 in the offset, and the 3rd and 4th have the same offset but different lengths.
Next, let's check the bytes behind that length byte and make another table:
0000 CITY.TXT 006B 00A5
007D CARSEL.RAW 6CD2 FD00
6D63 RUBBERFX.FT 0040 0076
6DB8 RUBBERFX.3DW 045F 0BF0
722C PSPOTFX2.TM 1CBA C000
This number is always somewhat larger than the first one. As we already suspect the file is compressed, I'd think that's the uncompressed size.
So you see, you can find out some stuff from just looking at the file itself. However, the question remains why the offsets in table 1 aren't constant, and which type of compression gets used. And, this is where you need a lot of experience and/or luck. Either, you've been using compression programs 20 years ago and remember some of them and their file formats, and this looks just like on of them. (It doesn't, to me, it's neither ARC nor ZIP). Or, you need to disassemble the file and check how the code does it. Unfortunately, I'm afraid there is no other way.