Merge branch 'develop-SoapyMan' into refactor-LEADAI

This commit is contained in:
Ilya Shurumov 2020-11-21 17:53:45 +06:00
commit 9892b713ea
124 changed files with 8136 additions and 5210 deletions

12
.appveyor/AfterBuild.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
set config=Debug:Release:Release_dev
for %%c in (%config::= %) do (
cd %project_folder%\bin\%%c
copy %windows_sdl2_dir%\lib\x86\SDL2.dll SDL2.dll /Y
copy %windows_openal_dir%\bin\Win32\soft_oal.dll OpenAL32.dll /Y
xcopy /e /v %data_folder% .\ /Y
7z a "REDRIVER2_%%c.zip" ".\*"
)

8
.appveyor/AfterBuild.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -ex
for config in debug release release_dev
do
cd "${APPVEYOR_BUILD_FOLDER}/src_rebuild/bin/${config^}"
tar -czf "REDRIVER2_${config^}.tar.gz" *
done

18
.appveyor/Build.bat Normal file
View File

@ -0,0 +1,18 @@
@echo off
cd %project_folder%
ren "%windows_jpeg_dir%\jconfig.vc" "jconfig.h"
set JPEG_DIR=%windows_jpeg_dir%
set OPENAL_DIR=%windows_openal_dir%
set SDL2_DIR=%windows_sdl2_dir%
premake5 vs2019
set config=Debug:Release:Release_dev
for %%c in (%config::= %) do (
msbuild .\REDRIVER2.sln /p:Configuration="%%c" /p:Platform=Win32 /m ^
/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" ^
/nologo /ConsoleLoggerParameters:NoSummary;Verbosity=quiet
)

11
.appveyor/Build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -ex
cd "$APPVEYOR_BUILD_FOLDER/src_rebuild"
./premake5 gmake2
for config in debug release release_dev
do
make config=$config -j$(nproc)
done

13
.appveyor/Install.bat Normal file
View File

@ -0,0 +1,13 @@
@echo off
appveyor DownloadFile %windows_premake_url% -FileName premake5.zip
7z x premake5.zip -o%project_folder%
appveyor DownloadFile %windows_jpeg_url% -FileName JPEG.zip
7z x JPEG.zip -o%dependency_folder%
appveyor DownloadFile %windows_openal_url% -FileName OPENAL.zip
7z x OPENAL.zip -o%dependency_folder%
appveyor DownloadFile %windows_sdl2_url% -FileName SDL2.zip
7z x SDL2.zip -o%dependency_folder%

19
.appveyor/Install.sh Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -ex
cd "$APPVEYOR_BUILD_FOLDER/src_rebuild"
# Download premake5
# because it isn't in the repos (yet?)
curl "$linux_premake_url" -Lo premake5.tar.gz
tar xvf premake5.tar.gz
sudo apt-get update -qq -y
sudo apt-get install -qq aptitude -y
# fix Ubuntu's broken mess of packages using aptitude
sudo aptitude install --quiet=2 \
g++-multilib libsdl2-2.0-0:i386 libsdl2-dev:i386 \
libopenal1:i386 libopenal-dev:i386 libjpeg-turbo8:i386 \
libjpeg-turbo8-dev:i386 -y

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

6
.gitignore vendored
View File

@ -15,10 +15,14 @@
*.ilk
*.code-workspace
.vscode/*
_OLD/
.vs/*
OTHER/*
Driver1/*
d1_xm_fix/*
dump_music/*
GAME/*
Ghidra/*
ART/*
symdump-decompile/*
PSX_BINS/*
PSX_BINS_ITALIAN/*

View File

@ -13,7 +13,6 @@ First use [premake5](https://github.com/premake/premake-core/releases/download/v
Dependencies (links for Windows):
- [SDL 2](https://www.libsdl.org/release/SDL2-devel-2.0.12-VC.zip)
- [GLEW](https://netix.dl.sourceforge.net/project/glew/glew/2.1.0/glew-2.1.0-win32.zip)
- [OpenAL-Soft](https://openal-soft.org/openal-binaries/openal-soft-1.20.1-bin.zip)
- [JPEG](http://www.ijg.org/files/jpegsr9d.zip)
@ -22,7 +21,6 @@ You need to download all the dependencies and extract them.
After set next environment variables like:
```
SDL2_DIR = <your_dependency_folder>\SDL2-2.0.12
GLEW_DIR = <your_dependency_folder>\glew-2.1.0
OPENAL_DIR = <your_dependency_folder>\openal-soft-1.20.1-bin
JPEG_DIR = <your_dependency_folder>\jpeg-9d
```
@ -44,8 +42,4 @@ Or just run `gen_vc2019.bat` (Windows only)
- **SLES-02996/SLES-12996** - 1.0 Italian version (look for ITALIAN.SYM existance)
# Game Content
After you have built game executable you would want to copy entire DRIVER2 folder from game CD or image to location where executable is located.
STR files and XA files for now are converted using JPSXDec.
- STR -> AVI (mjpg)
- XA -> multiple WAV files
See [Wiki/Installation Instructions](https://github.com/OpenDriver2/REDRIVER2/wiki/Installation-instructions)

View File

@ -24,10 +24,11 @@ Start Date: 28 March 2019
- All information (variables, types and function names) have been obtained from debugging symbols (.SYM), driver_psx_level and DLE
- Ghidra project (based on Italian SYM) to deal with overlays, simple code complex branching - semi-auto decompilation
- IDB based on Spanish SYM when dealing with things Ghidra can't handle properly - manual decompilation (mostly GTE code)
- Originally targeted *Playstation* game built upon [Psy-X (Psy-Cross) (formely extended TOMB5 emulator)](https://github.com/OpenDriver2/REDRIVER2/tree/master/src_rebuild/PsyX)
### How to use
See [Wiki/Installation Instructions](https://github.com/OpenDriver2/REDRIVER2/wiki/Installation-instructions)
### Usage
Assuming you have compiled the most recent code or got artifacts from Appveyor.
Copy DRIVER2 folder from your **game CD** to location where compiled EXE is located.
### Credits
- Soapy - lead programmer

View File

@ -1,4 +1,4 @@
version: 3.0.{build}
version: 5.3.{build}
branches:
only:
@ -7,64 +7,44 @@ branches:
skip_tags: true
image: Visual Studio 2019
configuration:
- Debug
- Release
- 'Release Dev'
clone_folder: 'c:\projects\REDRIVER2'
#lib_folder: %clone_folder%\EXTERNAL
image:
- Visual Studio 2019
- Ubuntu
environment:
data_folder: 'c:\projects\REDRIVER2\data'
project_folder: 'c:\projects\REDRIVER2\src_rebuild'
dependency_folder: '%project_folder%\dependencies'
data_folder: '%APPVEYOR_BUILD_FOLDER%\data'
project_folder: '%APPVEYOR_BUILD_FOLDER%\\src_rebuild'
dependency_folder: '%APPVEYOR_BUILD_FOLDER%\dependencies'
# Dependency URLs
windows_premake_url: 'https://github.com/premake/premake-core/releases/download/v5.0.0-alpha15/premake-5.0.0-alpha15-windows.zip'
windows_jpeg_url: 'http://www.ijg.org/files/jpegsr9d.zip'
windows_openal_url: 'https://openal-soft.org/openal-binaries/openal-soft-1.20.1-bin.zip'
windows_sdl2_url: 'https://www.libsdl.org/release/SDL2-devel-2.0.12-VC.zip'
linux_premake_url: 'https://github.com/premake/premake-core/releases/download/v5.0.0-alpha15/premake-5.0.0-alpha15-linux.tar.gz'
# Dependency Directories
windows_jpeg_dir: '%dependency_folder%\jpeg-9d'
windows_openal_dir: '%dependency_folder%\openal-soft-1.20.1-bin'
windows_sdl2_dir: '%dependency_folder%\SDL2-2.0.12'
build:
project: c:\projects\REDRIVER2\src_rebuild\REDRIVER2.sln
verbosity: minimal
install:
- cmd: '%APPVEYOR_BUILD_FOLDER%\.appveyor\Install.bat'
- sh: '${APPVEYOR_BUILD_FOLDER}/.appveyor/Install.sh'
build_script:
- cmd: '%APPVEYOR_BUILD_FOLDER%\.appveyor\Build.bat'
- sh: '${APPVEYOR_BUILD_FOLDER}/.appveyor/Build.sh'
after_build:
- cmd: '%APPVEYOR_BUILD_FOLDER%\.appveyor\AfterBuild.bat'
- sh: '${APPVEYOR_BUILD_FOLDER}/.appveyor/AfterBuild.sh'
cache:
- '%project_folder%\obj\%configuration%\'
platform:
- Win32
#- x64
install:
- set SDL2_URL="https://www.libsdl.org/release/SDL2-devel-2.0.12-VC.zip"
- appveyor DownloadFile %SDL2_URL% -FileName SDL2.zip
- 7z x SDL2.zip -o%dependency_folder%
- set OPENAL_URL="https://openal-soft.org/openal-binaries/openal-soft-1.20.1-bin.zip"
- appveyor DownloadFile %OPENAL_URL% -FileName OPENAL.zip
- 7z x OPENAL.zip -o%dependency_folder%
- set JPEG_URL="http://www.ijg.org/files/jpegsr9d.zip"
- appveyor DownloadFile %JPEG_URL% -FileName JPEG.zip
- 7z x JPEG.zip -o%dependency_folder%
- set PREMAKE_URL="https://github.com/premake/premake-core/releases/download/v5.0.0-alpha15/premake-5.0.0-alpha15-windows.zip"
- appveyor DownloadFile %PREMAKE_URL% -FileName premake5.zip
- 7z x premake5.zip -o%project_folder%
- set SDL2_DIR=%dependency_folder%\SDL2-2.0.12
- set OPENAL_DIR=%dependency_folder%\openal-soft-1.20.1-bin
- set JPEG_DIR=%dependency_folder%\jpeg-9d
before_build:
- cmd: cd %project_folder%
- cmd: premake5 vs2019
- cmd: ren "%JPEG_DIR%\jconfig.vc" "jconfig.h"
- 'src_rebuild\obj\'
artifacts:
- path: src_rebuild\bin\%configuration%\*.zip
name: Binaries
after_build:
- cmd: cd %project_folder%\bin\%configuration%
- cmd: copy %SDL2_DIR%\lib\x86\SDL2.dll SDL2.dll /Y
- cmd: copy %OPENAL_DIR%\bin\Win32\soft_oal.dll OpenAL32.dll /Y
- cmd: copy %data_folder%\config.ini config.ini /Y
- 7z a "REDRIVER2_%configuration%.zip" ".\*"
#build: off
- path: src_rebuild\bin\*\*.zip
name: Windows Binaries
- path: src_rebuild\bin\*\*.tar.gz
name: Linux Binaries

37
changelog.txt Normal file
View File

@ -0,0 +1,37 @@
## Changelog since Oct 12 2000 (1.0 release build)
### Gameplay:
- Improved cop AI batter logic to better balance difficulty
- Restored Tanner felony (can be seen in two Vegas missions)
- Cops no longer can see player if on different heights
- Fixed cop AI activation when player without felony touches roadblock car
- Fixed and improved Cop AI navigation/pathfinding
- Fixed player car drowning bug in tunnels
- Fixed Tanner "drowning" by non-moving train in Vegas Ghost Town
- Restored Tanner drowning movement in water
- Fixed Tanner sitting on chairs
- Easier jump in "Boat Jump"
- Featured Driver Madness community chases by **Olanov, VortexStory, RacingFreak, Snoopi, Fireboyd78** and **SoapyMan**
### Effects/Visuals:
- In-game cutscene subtitles
- Improved draw distance and resolved glitches
- Restored street lamp damage
- Restored street light trails
- Fixed some polygons not drawing (Chicago Goose island's white barrels)
- Car lost hubcaps are now bound to single car
- Restored Havana secret car elevator sound
- Restored multiplayer follow camera
- Restored car engine smoke
- Leaves are now affected properly by player car and chased car
### Film Director:
- Fix camera invalidation bugs
- Added variable zoom for non-locked tripod camera
- Added target height adjustment to locked tripod camera
- Improved chase camera, restored height and distance editing
### Other:
- PC version now automatically saves undercover campaign progress
- PC version now has command line arguments
- Memory card overlay removed

View File

@ -0,0 +1,279 @@
REFLECTIONS
(In alphabetical order)
GAME CONCEPT AND DEVELOPMENT DIRECTOR
Martin Edmondson
PROJECT MANAGEMENT
Gareth Edmondson
Tony M Roberts
PROGRAMMING TEAM
Steve Burrows
Jon Head
James Hopkin
Russ Lazzari
Will Musson
Christopher Phillips (Lead Technical)
Jeanette Phillips
ADDITIONAL PROGRAMMING
Wayne Coles
Chris Jenner
CITY ART TEAM
Dave Oxford (Art Manager)
CHICAGO
Mike Thompson
Chris Willacy
HAVANA
Steven Adams
Andreas Tawn
LAS VEGAS
Andrew Bales
Carl Jackson
Dave Oxford Jnr
Andrew Sharratt
RIO
Andrew Bales
Dave Oxford Jnr
ADDITIONAL ARTWORK
Phil Baxter
Jack Couvela
Richard Daglish
Paul Foster
Michael Jeffries
Alex Mallinson
Daniel Oxford
CUT SCENE ANIMATION TEAM
Mark Akester
Robin Armstrong
Davo Cockburn
Marcus Hardy
Matthew Hughes
Doug Lewis (Storyboarding)
Simon McKeown (Head of Animation)
Jonathan Redhead
Richard Robinson
GAME DESIGN
Martin Edmondson
Craig Lawson
SCREEN PLAY
Maurice Suckling
MISSION SCRIPTING
James Hume
Martin Oliver
IN HOUSE TESTING
William Brown
ADDITIONAL CREDITS
VOICE RECORDING
Arranged by
All in the Game Ltd
POST PRODUCTION & SOUND EFFECTS
Supplied by PC Music Ltd
LOCALISATION
Browns Language Services
SPECIAL THANKS:
Giselle Stewart (General Manager)
Alistair Brimble
Lee Kirton
Keith Leary
North East American Car Club
Forsters of Consett
Viewpoint Digital
Deadline Technical Services
Daniel Matray
Mz.Lynn.Danielz.
INFOGRAMES
An Infogrames Motion Production
EXECUTIVE VICE-PRESIDENT, PRODUCTION AND PUBLISHING
Jean-Philippe Agati
HEAD OF LABEL - INFOGRAMES MOTION
Olivier Goulay
INFOGRAMES MOTION PRODUCTION TEAM
Gareth Betts
Ivan Davies
Eric Labelle
Jay Sharples
INFOGRAMES MOTION MARKETING TEAM
Larry Sparks
Monique Crusot
Cindy Church
Lynn Daniel
Florence Rigaut
Anne Roy
Renaud Marin
Richard Hall
Daniel Matray
INFOGRAMES EUROPE SHEFFIELD Q.A TEAM
Lewis Glover
Robert Lunt
Phil Eckford
SPECIAL Q.A THANKS
Carrie Hobson
Dan Webster
TESTERS
Martin Berridge
Steve Woodward
Rob Taylor
Wayne Adkin
Dominic Hartley
Stef Reali
Jack Bishop
INFOGRAMES EUROPE LYON Q.A TEAM
Stephane Pradier
Stephane Charrier
Christian Ampere
Xavier Martin
Hakim Belayati
Philippe Trignat
Manuel "Franchu" Rubira
ADDITIONAL THANKS
The remaining Sheffield Q.A Dept
James McCarthy
INFOGRAMES LOCALISATION GROUP
Sylviane Pivot
Valerie Maillot
Sarah Bennett
Danielle Perez
Beatrice Rodriguez
Monica Steinhauer
SPECIAL THANKS:
Jim Murdoch
Rebecka Pernered
Sophie Wibaux
Jean Marcel Nicolai
Audrey Chapot
Paul Fox
Matt Woodley
Mercier Gray
Red Pepper Design
INFOGRAMES DISTRIBUTION EUROPE
Penrose Tackie
Lee Kirton
Alexandre Enklaar
Arnaud Blacher
Cecile Fouques Du Parc
Jerome Barbe
Duarte Nuno
Beatriz Doval
Aida Guerra
Frans Mittermayer
Achim Schmauss
Guido Alt
Corine Beroud
Mathieu Brossette
Bart Hufen
Matt Broughton
Louise Malouf
Kym Warner
MUSIC
Dust Junkies - Fever
Nicholas Lockett / Sam Hickling / Stephen Jones / Paul Billington.
Published by Universal Music Publishing Limited / Copyright Control.
P&C 1996 Polydor Ltd (UK)
Etta James - In The Basement
Composed by Raynard Miner / Billy Davis / Carl Smith. Published by Chevis
Publishing Corp. By permission of EMI Music Publishing Ltd. P&C 1966 MCA
Records Inc
Sonny Boy Williamson - HELP ME
Composed by Sonny Boy Williamson, Willie Dixon and Ralph Bass.
Copyright Arc Music Corp and Hoochie Coochie Music Music. Used by kind
permission of Jewel Music Ltd and Bug Music Ltd. P&C 1963 MCA Records Inc
Hound Dog Taylor & The House Rockers - Sitting At Home Alone
Written by Theodore R. Taylor. Published by Gazell Publishing International
for Eyeball Music and Alligator Records. P&C 1973 Alligator Records
Kenny Rogers - Just Dropped In
Written by Mickey Newbury. Published by Acuff Rose Music Publishing.
P&C 1985 MCA Records Inc
Mozart - Lacrimosa
Couresy of The Decca Record Company Limited. Licensed by kind permission
from The Film & TV Licensing Division, part of the Universal Music Group
IN GAME MUSIC
Alistair Brimble
Semi-Precious Studios
Richard Narco
All events and characters depicted in this game are fictitious. Any similarity
to actual persons, living or dead, is purely coincidental.
Driver 2 (C)2000 Infogrames. All rights Reserved. Created by Reflections
Interactive Limited, an Infogrames, Inc studio. Published & distributed by
Infogrames. Reflections and the Reflections logo are trademarks of Reflections
Interactive Limited. Infogrames and the Infogrames logo are trademarks of
Infogrames. All other trademarks are the property of their respective companies.
Tanner and Jones last seen in 2011

View File

@ -11,5 +11,8 @@ bilinearFiltering=0
pgxpZbuffer=0
[game]
drawDistance=600
freeCamera=1
drawDistance=1200
freeCamera=1
driver1music=0
widescreenOverlays=0
userChases=RacingFreak,Snoopi,Olanov,Vortex,Fireboyd78

View File

@ -0,0 +1,25 @@
[settings]
loadExistingCutscene=1
mission=6
baseMission=50
subindex=2
streams=2
player=0
[stream0]
type=2 # 1=car, 2=tanner
model=0
palette=0
controlType=1 # 1=player, 7=cutscene
startRot=2048
startPosX=-36898
startPosZ=267729
[stream1]
type=1 # 1=car, 2=tanner
model=1
palette=0
controlType=7 # 1=player, 7=cutscene
startRot=2048
startPosX=-39288
startPosZ=263528

View File

@ -144,40 +144,40 @@ void HandleThrownBombs(void)
int dx, dz;
VECTOR velocity;
if (gBombTargetVehicle == NULL)
return;
ThrownBombDelay--;
if (ThrownBombDelay == -1)
// throw bombs if we have vehicle
if (gBombTargetVehicle)
{
ThrownBombDelay = Random2(0) % 45 + 8;
ThrownBombDelay--;
bomb = &ThrownBombs[CurrentBomb++];
CurrentBomb = CurrentBomb % MAX_THROWN_BOMBS;
if (ThrownBombDelay == -1)
{
ThrownBombDelay = Random2(0) % 45 + 8;
bomb->flags = 1;
bomb->active = 1;
bomb = &ThrownBombs[CurrentBomb++];
CurrentBomb = CurrentBomb % MAX_THROWN_BOMBS;
bomb->position.vx = gBombTargetVehicle->hd.where.t[0];
bomb->position.vy = gBombTargetVehicle->hd.where.t[1] - 200;
bomb->position.vz = gBombTargetVehicle->hd.where.t[2];
bomb->flags = 1;
bomb->active = 1;
velocity.vx = FIXEDH(gBombTargetVehicle->st.n.linearVelocity[0]);
velocity.vy = 0;
velocity.vz = FIXEDH(gBombTargetVehicle->st.n.linearVelocity[2]);
bomb->position.vx = gBombTargetVehicle->hd.where.t[0];
bomb->position.vy = gBombTargetVehicle->hd.where.t[1] - 200;
bomb->position.vz = gBombTargetVehicle->hd.where.t[2];
bomb->velocity.vx = velocity.vx >> 10;
bomb->velocity.vz = velocity.vz >> 10;
bomb->velocity.vy = -(Long2DDistance(&bomb->position, (VECTOR *)player[0].pos) >> 7);
velocity.vx = FIXEDH(gBombTargetVehicle->st.n.linearVelocity[0]);
velocity.vz = FIXEDH(gBombTargetVehicle->st.n.linearVelocity[2]);
if ((rand() & 1) == 0)
bomb->rot_speed = -bomb->velocity.vy;
else
bomb->rot_speed = bomb->velocity.vy;
bomb->velocity.vx = velocity.vx >> 10;
bomb->velocity.vz = velocity.vz >> 10;
bomb->velocity.vy = -(Long2DDistance(&bomb->position, (VECTOR *)player[0].pos) >> 7);
if (bomb->velocity.vy < -100)
bomb->velocity.vy = -100;
if ((rand() & 1) == 0)
bomb->rot_speed = -bomb->velocity.vy;
else
bomb->rot_speed = bomb->velocity.vy;
if (bomb->velocity.vy < -100)
bomb->velocity.vy = -100;
}
}
bomb = ThrownBombs;
@ -185,7 +185,7 @@ void HandleThrownBombs(void)
i = 0;
while (i < MAX_THROWN_BOMBS)
{
if ((bomb->flags & 1) != 0)
if (bomb->flags & 1)
{
bomb->position.vx += bomb->velocity.vx;
bomb->position.vy += bomb->velocity.vy;
@ -237,7 +237,7 @@ void HandleThrownBombs(void)
}
bomb++;
i++;
};
}
}

View File

@ -21,6 +21,7 @@
#include "INLINE_C.H"
#include "LIBGTE.H"
#include "MAP.H"
#include "PEDEST.H"
VECTOR gCameraOffset = { 0};
@ -308,7 +309,7 @@ void ModifyCamera(void)
int i;
if (NoPlayerControl == 0 && cameraview != 6 && events.cameraEvent == NULL);// && NumPlayers == 1) // [A] allow switching cameras in multiplayer
if (NoPlayerControl == 0 && cameraview != 6 && events.cameraEvent == NULL) // && NumPlayers == 1) // [A] allow switching cameras in multiplayer
{
for(i = 0; i < NumPlayers; i++)
{
@ -1006,11 +1007,13 @@ void PlaceCameraInCar(PLAYER *lp, int BumperCam)
{
_RotMatrixY(&inv_camera_matrix, 0x800);
_RotMatrixY(&inv_camera_matrix, (lp->headPos >> 16));
if (cp != NULL)
viewer_position.vz = -170;
else
_RotMatrixX(&inv_camera_matrix, -tannerLookAngle.vx);
}
MulMatrix0(&aspect, &inv_camera_matrix, &inv_camera_matrix);
InvertMatrix(&inv_camera_matrix, &camera_matrix);

View File

@ -43,7 +43,9 @@ HUBCAP gHubcap;
// active cars
CAR_DATA* active_car_list[MAX_CARS];
BOUND_BOX bbox[MAX_CARS];
unsigned char lightsOnDelay[MAX_CARS];
u_char lightsOnDelay[MAX_CARS];
u_short civ_clut[8][32][6];
// decompiled code
// original method signature:
@ -1229,14 +1231,14 @@ void DrawCarWheels(CAR_DATA *cp, MATRIX *RearMatrix, VECTOR *pos, int zclip)
VertPtr[11].vz = -FW2z;
VertPtr[12].vz = -FW2z;
VertPtr[0x17].vz = 0;
VertPtr[0x16].vz = 0;
VertPtr[0x15].vy = 0;
VertPtr[0x14].vy = 0;
VertPtr[0x13].vy = 0;
VertPtr[0x12].vy = 0;
VertPtr[0x11].vz = 0;
VertPtr[0x10].vz = 0;
VertPtr[23].vz = 0;
VertPtr[22].vz = 0;
VertPtr[21].vy = 0;
VertPtr[20].vy = 0;
VertPtr[19].vy = 0;
VertPtr[18].vy = 0;
VertPtr[17].vz = 0;
VertPtr[16].vz = 0;
VertPtr[23].vy = wheelSize;
VertPtr[22].vy = wheelSize;
@ -1273,14 +1275,14 @@ void DrawCarWheels(CAR_DATA *cp, MATRIX *RearMatrix, VECTOR *pos, int zclip)
VertPtr[11].vz = -BW2z;
VertPtr[12].vz = -BW2z;
VertPtr[0x17].vz = 0;
VertPtr[0x16].vz = 0;
VertPtr[0x15].vy = 0;
VertPtr[0x14].vy = 0;
VertPtr[0x13].vy = 0;
VertPtr[0x12].vy = 0;
VertPtr[0x11].vz = 0;
VertPtr[0x10].vz = 0;
VertPtr[23].vz = 0;
VertPtr[22].vz = 0;
VertPtr[21].vy = 0;
VertPtr[20].vy = 0;
VertPtr[19].vy = 0;
VertPtr[18].vy = 0;
VertPtr[17].vz = 0;
VertPtr[16].vz = 0;
VertPtr[23].vy = wheelSize;
VertPtr[22].vy = wheelSize;
@ -1294,7 +1296,7 @@ void DrawCarWheels(CAR_DATA *cp, MATRIX *RearMatrix, VECTOR *pos, int zclip)
SteerMatrix.m[0][0] = rcossin_tbl[(cp->wheel_angle & 0xfff) * 2 + 1];
SteerMatrix.m[0][2] = rcossin_tbl[(cp->wheel_angle & 0xfff) * 2];
SteerMatrix.m[1][1] = 4096;
SteerMatrix.m[1][1] = ONE;
SteerMatrix.m[2][1] = 0;
SteerMatrix.m[1][2] = 0;
SteerMatrix.m[1][0] = 0;
@ -2349,6 +2351,57 @@ char GetCarPalIndex(int tpage)
}
// [D]
void ProcessPalletLump(char *lump_ptr, int lump_size)
{
if (gDriver1Level) // [A]
return; // TODO: load Driver 1 civ palettes
ushort clutValue;
int *buffPtr;
int texnum;
int palette;
u_short *clutTablePtr;
u_short clutTable[320];
int tpageindex;
int total_cluts;
int clut_number;
if (*(int*)lump_ptr == 0 || *(int*)(lump_ptr + 4) == -1)
return;
buffPtr = (int*)(lump_ptr + 4);
clutTablePtr = (u_short*)clutTable;
do
{
palette = buffPtr[0];
texnum = buffPtr[1];
tpageindex = buffPtr[2];
total_cluts = buffPtr[3];
clut_number = GetCarPalIndex(tpageindex);
if (total_cluts == -1)
{
LoadImage(&clutpos, (u_long*)(buffPtr + 4));
clutValue = GetClut(clutpos.x, clutpos.y);
*clutTablePtr = clutValue;
clutTablePtr += 1;
IncrementClutNum(&clutpos);
buffPtr += 12;
}
else
{
clutValue = clutTable[total_cluts];
buffPtr += 4;
}
civ_clut[clut_number][texnum][palette + 1] = clutValue;
}
while (*buffPtr != -1);
}

View File

@ -38,6 +38,8 @@ extern short BackWheelRotation[MAX_CARS];
extern char LeftLight;
extern char RightLight;
extern u_short civ_clut[8][32][6];
extern void plotNewCarModel(CAR_MODEL *car, int palette); // 0x00020C94
extern void plotCarPolyB3(int numTris, CAR_POLY *src, SVECTOR *vlist, plotCarGlobals *pg); // 0x000237B8

View File

@ -90,6 +90,10 @@ PACKED_CELL_OBJECT * GetFirstPackedCop(int cellx, int cellz, CELL_ITERATOR *pci,
if (NumPlayers == 2)
#endif // else do this check always
{
// [A] don't draw loading region
if (loading_region[index] != -1)
return NULL;
if (RoadMapRegions[index] != (cellx / MAP_REGION_SIZE) + (cellz / MAP_REGION_SIZE) * (cells_across / MAP_REGION_SIZE))
return NULL;
}

View File

@ -18,7 +18,6 @@
#include "GAMESND.H"
#include "SOUND.H"
#include "BCOLLIDE.H"
#include "GLAUNCH.H"
#include "LEADAI.H"
#include "MAIN.H"
#include "PEDEST.H"
@ -26,8 +25,9 @@
#include "INLINE_C.H"
#include "OVERLAY.H"
#include "STRINGS.H"
unsigned char speedLimits[3] = { 56, 97, 138 };
const u_char speedLimits[3] = { 56, 97, 138 };
struct
{
@ -917,38 +917,9 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
{
cp->ai.c.ctrlState = 0;
if ((junctionFlags & 1) == 0)
{
int yield = 0;
if (exitFrom == 0 || exitFrom == 2)
yield = 1;
if ((junctionFlags & 2) == 0)
{
cp->ai.c.ctrlState = 4;
if (!yield)
cp->ai.c.ctrlNode = oldNode;
else if (*turnAngle != 0)
cp->ai.c.ctrlNode = oldNode;
else
cp->ai.c.ctrlState = 6;
}
else
{
cp->ai.c.ctrlState = 4;
if (yield)
cp->ai.c.ctrlNode = oldNode;
else if (*turnAngle != 0)
cp->ai.c.ctrlNode = oldNode;
else
cp->ai.c.ctrlState = 6;
}
}
else
if (junctionFlags & 1)
{
// wait for traffic light
cp->ai.c.trafficLightPhaseId = (exitFrom & 1);
cp->ai.c.ctrlState = 1;
@ -962,6 +933,36 @@ int GetNextRoadInfo(CAR_DATA* cp, int randomExit, int* turnAngle, int* startDist
else
cp->ai.c.ctrlNode = oldNode;
}
else
{
int yield = 0;
if (exitFrom == 0 || exitFrom == 2)
yield = 1;
if (junctionFlags & 2)
{
cp->ai.c.ctrlState = 4;
if (yield)
cp->ai.c.ctrlNode = oldNode;
else if (*turnAngle != 0)
cp->ai.c.ctrlNode = oldNode;
else
cp->ai.c.ctrlState = 6;
}
else
{
cp->ai.c.ctrlState = 4;
if (!yield)
cp->ai.c.ctrlNode = oldNode;
else if (*turnAngle != 0)
cp->ai.c.ctrlNode = oldNode;
else
cp->ai.c.ctrlState = 6;
}
}
}
if(!GetSurfaceRoadInfo(&roadInfo, newRoad))
@ -2248,8 +2249,8 @@ int CreateNewNode(CAR_DATA * cp)
if (tmp > 0)
{
newNode->x = start->x + FIXEDH(tmp * rcossin_tbl[(start->dir & 0xfff) * 2]);
newNode->z = start->z + FIXEDH(tmp * rcossin_tbl[(start->dir & 0xfff) * 2 + 1]);
newNode->pathType = 1;
newNode->dir = start->dir;
@ -2263,6 +2264,7 @@ int CreateNewNode(CAR_DATA * cp)
{
retNode->x = tempNode.x + FIXEDH(tmp * rcossin_tbl[(tempNode.dir & 0xfff) * 2]);
retNode->z = tempNode.z + FIXEDH(tmp * rcossin_tbl[(tempNode.dir & 0xfff) * 2 + 1]);
retNode->pathType = 1;
retNode->dir = tempNode.dir;
@ -2277,13 +2279,9 @@ int CreateNewNode(CAR_DATA * cp)
newNode->pathType = tempNode.pathType;
newNode->distAlongSegment = tempNode.distAlongSegment;
newNode->x = tempNode.x;
if (tempNode.x < 0)
tempNode.x = -tempNode.x;
newNode->z = tempNode.z;
if (tempNode.x < 600000)
if (ABS(tempNode.x) < 600000)
{
if (turnAngle != 0)
{
@ -2292,6 +2290,7 @@ int CreateNewNode(CAR_DATA * cp)
}
newNode->pathType = 1;
return 1;
}
}
@ -2499,13 +2498,14 @@ int PingOutAllSpecialCivCars(void)
lcp = car_data;
do
{
if (lcp->controlType == CONTROL_TYPE_CIV_AI && MissionHeader->residentModels[lcp->ap.model] > 4)
PingOutCar(lcp);
lcp++;
}
while (lcp < &car_data[MAX_CARS])
while (lcp < &car_data[MAX_CARS]);
return 1;
}
@ -2767,6 +2767,17 @@ void InitCivCars(void)
roadblockDelay = roadblockDelayDiff[gCopDifficultyLevel] + (Random2(0) & 0xff);
PingOutCivsOnly = 0;
roadblockCount = roadblockDelay;
// [A] clear out other values
distFurthestCivCarSq = 0;
furthestCivID = 0;
makeLimoPullOver = 0;
limoId = 0;
playerNum = 0;
roadSeg = 0;
testNumPingedOut = 0;
currentAngle = 0;
closeEncounter = 3;
}
@ -3258,8 +3269,9 @@ int PingInCivCar(int minPingInDist)
int lbody;
int lane;
int i;
int oldCookieCount;
u_char cookieCountStart;
uint retDistSq;
unsigned char* slot;
//straight = NULL;
//curve = NULL;
@ -3286,12 +3298,12 @@ int PingInCivCar(int minPingInDist)
tryPingInParkedCars = 1;
}
playerNum = 0;
if (NumPlayers == 2)
playerNum = CameraCnt & 1;
else
playerNum = 0;
if ((MissionHeader->type & 4U) != 0)
if (MissionHeader->type & 0x4)
{
PingOutCivsOnly = 1;
return 0;
@ -3334,8 +3346,8 @@ int PingInCivCar(int minPingInDist)
if (newCarId == -1)
return 0;
if (newCarId > MAX_CARS - 1)
return 0;
//if (newCarId > MAX_CARS - 1)
// return 0;
newCar = &car_data[newCarId];
@ -3369,13 +3381,14 @@ int PingInCivCar(int minPingInDist)
// randomized pings
int angle;
int dx, dz;
unsigned char* slot;
const int maxCookies = requestCopCar ? 55 : 43;
if (requestCopCar == 0 && cookieCount > 43)
cookieCount -= 25;
cookieCountStart = cookieCount;
// find a free slot
carCnt = car_data;
slot = reservedSlots;
@ -3397,16 +3410,16 @@ int PingInCivCar(int minPingInDist)
return 0;
}
oldCookieCount = cookieCount;
do {
if (cookieCount < maxCookies)
cookieCount++;
else
cookieCount = 0;
if (cookieCount == oldCookieCount)
if (cookieCount == cookieCountStart)
{
break;
}
if (requestCopCar == 0)
{
@ -3438,9 +3451,9 @@ int PingInCivCar(int minPingInDist)
}
{
int numPossibleLanes;
int numLanes;
int allowedToPark;
volatile int numPossibleLanes;
volatile int numLanes;
volatile int allowedToPark;
if (ROAD_LANES_COUNT(&roadInfo) == 0) // BAD ROAD
{
@ -3958,6 +3971,11 @@ int CivControl(CAR_DATA * cp)
VECTOR b1p = { pn->x, cp->hd.where.t[1], pn->z };
if (pn->pathType == 2)
{
ofs.vy = 1000;
}
//Debug_AddLineOfs(_zero, _up, b1p, rrcv);
Debug_AddLineOfs(_zero, ofs, b1p, rrcv);
}
@ -4167,77 +4185,68 @@ int CivAccelTrafficRules(CAR_DATA * cp, int* distToNode)
switch (cp->ai.c.thrustState)
{
case 0:
{
cp->ai.c.brakeLight = 0;
if (cp->ai.c.ctrlNode)
case 0:
{
int properVel;
int brakeDist;
cp->ai.c.brakeLight = 0;
if (!IS_NODE_VALID(cp, cp->ai.c.ctrlNode))
if (cp->ai.c.ctrlNode)
{
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
int properVel;
int brakeDist;
properVel = cp->hd.wheel_speed;
brakeDist = (properVel * FIXEDH(properVel)) / (newAccel * 2);
if (ABS(brakeDist) > * distToNode)
{
properVel -= 120000;
brakeDist = *distToNode - lbody * 3;
if (brakeDist < 0)
if (!IS_NODE_VALID(cp, cp->ai.c.ctrlNode))
{
if (lbody * 3 - *distToNode > 2)
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
properVel = cp->hd.wheel_speed;
brakeDist = (properVel * FIXEDH(properVel)) / (newAccel * 2);
if (ABS(brakeDist) > *distToNode)
{
properVel -= 120000;
brakeDist = *distToNode - lbody * 3;
if (brakeDist < 0)
{
if (lbody * 3 - *distToNode > 2)
{
properVel /= *distToNode - lbody * 3;
}
}
else if (brakeDist > 2)
{
properVel /= *distToNode - lbody * 3;
}
}
else if (brakeDist > 2)
{
properVel /= *distToNode - lbody * 3;
}
cp->ai.c.velRatio = properVel;
cp->ai.c.thrustState = 1;
cp->ai.c.velRatio = properVel;
cp->ai.c.thrustState = 1;
}
}
if (FIXEDH(cp->hd.wheel_speed) > cp->ai.c.maxSpeed)
return newAccel >> 2;
return newAccel;
}
if (FIXEDH(cp->hd.wheel_speed) > cp->ai.c.maxSpeed)
return newAccel >> 2;
return newAccel;
}
case 1:
{
int properVel;
int distToEnd;
int accelRatio;
if (cp->ai.c.ctrlState == 5 || cp->ai.c.ctrlState == 8)
distToEnd = 100;
else
distToEnd = lbody * 3;
cp->ai.c.brakeLight = 1;
if (cp->ai.c.ctrlNode != NULL && cp->ai.c.ctrlNode->pathType != 127)
case 1:
{
if (cp->ai.c.ctrlState == 1 && junctionLightsPhase[cp->ai.c.trafficLightPhaseId] == 3)
{
cp->ai.c.thrustState = 0;
cp->ai.c.ctrlNode = NULL;
int properVel;
int distToEnd;
int accelRatio;
return newAccel;
}
if (cp->ai.c.ctrlState == 5 || cp->ai.c.ctrlState == 8)
distToEnd = 100;
else
distToEnd = lbody * 3;
if (*distToNode < distToEnd)
cp->ai.c.brakeLight = 1;
if (cp->ai.c.ctrlNode != NULL && cp->ai.c.ctrlNode->pathType != 127)
{
if (cp->ai.c.ctrlState == 6)
if (cp->ai.c.ctrlState == 1 && junctionLightsPhase[cp->ai.c.trafficLightPhaseId] == 3)
{
cp->ai.c.thrustState = 0;
cp->ai.c.ctrlNode = NULL;
@ -4245,138 +4254,150 @@ int CivAccelTrafficRules(CAR_DATA * cp, int* distToNode)
return newAccel;
}
accelRatio = (-cp->hd.wheel_speed) / 4;
cp->ai.c.thrustState = 3;
}
else
{
if (cp->ai.c.ctrlState == 6)
if (*distToNode < distToEnd)
{
properVel = (*distToNode - distToEnd) * cp->ai.c.velRatio + 70000;
}
else if (distToEnd < *distToNode)
{
properVel = cp->ai.c.velRatio * ((*distToNode - distToEnd) + 100);
if (cp->ai.c.ctrlState == 6)
{
cp->ai.c.thrustState = 0;
cp->ai.c.ctrlNode = NULL;
return newAccel;
}
accelRatio = (-cp->hd.wheel_speed) / 4;
cp->ai.c.thrustState = 3;
}
else
{
properVel = 0;
if (cp->ai.c.ctrlState == 6)
{
properVel = (*distToNode - distToEnd) * cp->ai.c.velRatio + 70000;
}
else if (distToEnd < *distToNode)
{
properVel = cp->ai.c.velRatio * ((*distToNode - distToEnd) + 100);
}
else
{
properVel = 0;
}
accelRatio = ((properVel - cp->hd.wheel_speed) * newAccel) / 15;
}
accelRatio = ((properVel - cp->hd.wheel_speed) * newAccel) / 15;
if (IS_NODE_VALID(cp, cp->ai.c.ctrlNode)) // [A] Weird.
{
if (accelRatio <= newAccel)
{
if (accelRatio < newAccel * -2)
return newAccel * -2;
else
return accelRatio;
}
return newAccel;
}
}
if (IS_NODE_VALID(cp, cp->ai.c.ctrlNode)) // [A] Weird.
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
case 3:
{
break;
}
case 5:
case 6:
{
int distToObstacle;
int checkObstDist;
int carDir;
int dx, dz;
cp->ai.c.brakeLight = 1;
if (cp->ai.c.ctrlState == 4)
checkObstDist = 2048;
else
checkObstDist = 512;
carDir = cp->hd.direction & 0xfff;
distToObstacle = 0x7fffff;
lcp = &car_data[MAX_CARS-1];
while (lcp >= car_data)
{
if (accelRatio <= newAccel)
if (lcp->ai.c.thrustState != 3 && lcp != cp && lcp->controlType != CONTROL_TYPE_NONE)
{
if (accelRatio < newAccel * -2)
dx = lcp->hd.where.t[0] - cp->hd.where.t[0];
dz = lcp->hd.where.t[2] - cp->hd.where.t[2];
tangent = FIXEDH(dx * rcossin_tbl[carDir * 2] + dz * rcossin_tbl[carDir * 2 + 1]);
normal = FIXEDH(dx * rcossin_tbl[carDir * 2 + 1] - dz * rcossin_tbl[carDir * 2]);
if (tangent > 0)
{
if (ABS(normal) < wbody * sideMul * 6 && tangent < distToObstacle)
{
distToObstacle = tangent;
}
}
}
lcp--;
}
if (distToObstacle <= checkObstDist)
{
int speed;
speed = (-cp->hd.wheel_speed) / 4; // is that a brake dist?
if (speed <= newAccel)
{
if (speed < newAccel * -2)
return newAccel * -2;
else
return accelRatio;
return speed;
}
return newAccel;
}
}
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
case 3:
{
break;
}
case 5:
case 6:
{
int distToObstacle;
int checkObstDist;
int carDir;
int dx, dz;
cp->ai.c.brakeLight = 1;
if (cp->ai.c.ctrlState == 4)
checkObstDist = 2048;
else
checkObstDist = 512;
carDir = cp->hd.direction & 0xfff;
distToObstacle = 0x7fffff;
lcp = &car_data[MAX_CARS-1];
while (lcp >= car_data)
{
if (lcp->ai.c.thrustState != 3 && lcp != cp && lcp->controlType != CONTROL_TYPE_NONE)
{
dx = lcp->hd.where.t[0] - cp->hd.where.t[0];
dz = lcp->hd.where.t[2] - cp->hd.where.t[2];
tangent = FIXEDH(dx * rcossin_tbl[carDir * 2] + dz * rcossin_tbl[carDir * 2 + 1]);
normal = FIXEDH(dx * rcossin_tbl[carDir * 2 + 1] - dz * rcossin_tbl[carDir * 2]);
if (tangent > 0)
{
if (ABS(normal) < wbody * sideMul * 6 && tangent < distToObstacle)
{
distToObstacle = tangent;
}
}
}
lcp--;
}
if (distToObstacle <= checkObstDist)
{
int speed;
speed = (-cp->hd.wheel_speed) / 4; // is that a brake dist?
if (speed <= newAccel)
{
if (speed < newAccel * -2)
return newAccel * -2;
else
return speed;
}
cp->ai.c.ctrlState = 0;
cp->ai.c.thrustState = 0;
cp->ai.c.ctrlNode = 0;
return newAccel;
}
cp->ai.c.ctrlState = 0;
cp->ai.c.thrustState = 0;
cp->ai.c.ctrlNode = 0;
return newAccel;
}
default:
{
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
default:
{
CIV_STATE_SET_CONFUSED(cp);
return 0;
}
}
// switch lights
switch (cp->ai.c.ctrlState)
{
case 1:
if (junctionLightsPhase[cp->ai.c.trafficLightPhaseId] == 3)
cp->ai.c.thrustState = 0;
case 2:
cp->ai.c.brakeLight = 1;
return 0;
case 3:
cp->ai.c.thrustState = 5;
cp->ai.c.brakeLight = 1;
break;
case 4:
cp->ai.c.thrustState = 6;
cp->ai.c.brakeLight = 1;
break;
default:
cp->ai.c.brakeLight = 0;
break;
case 1:
if (junctionLightsPhase[cp->ai.c.trafficLightPhaseId] == 3)
cp->ai.c.thrustState = 0;
case 2:
cp->ai.c.brakeLight = 1;
return 0;
case 3:
cp->ai.c.thrustState = 5;
cp->ai.c.brakeLight = 1;
break;
case 4:
cp->ai.c.thrustState = 6;
cp->ai.c.brakeLight = 1;
break;
default:
cp->ai.c.brakeLight = 0;
break;
}
return 0;

View File

@ -1,7 +1,7 @@
#ifndef CIV_AI_H
#define CIV_AI_H
extern unsigned char speedLimits[3];
extern const u_char speedLimits[3];
extern unsigned char reservedSlots[MAX_CARS];
extern int frameStart;

View File

@ -19,10 +19,11 @@
#include "PAUSE.H"
#include "OVERMAP.H"
#include "DIRECTOR.H"
#include "XAPLAY.H"
#include "LIBETC.H"
#include "STRINGS.H"
#include "XAPLAY.H"
#include "RAND.H"
int gSkipInGameCutscene = 0;
@ -35,7 +36,7 @@ int gThePlayerCar = -1;
static int CutsceneStreamIndex = 0;
int CutsceneFrameCnt = 0;
static int NumCutsceneStreams = 0;
int NumCutsceneStreams = 0;
static int gHaveInGameCutscene = 0;
static int gCSDestroyPlayer = 0;
static int PreLoadedCutscene = -1;
@ -56,6 +57,52 @@ static int CutsceneCameraOffset = 0;
#ifndef PSX
char* gCustomCutsceneBuffer;
char gUserReplayFolderList[MAX_USER_REPLAYS][48];
int gNumUserChases = 0;
int gUserChaseLoaded = -1;
// [A] user replay folders initialization
void InitUserReplays(const char* str)
{
int quit;
char* ptr;
char* strStart;
gNumUserChases = 0;
if (!str)
return;
ptr = (char*)str;
strStart = NULL;
memset(gUserReplayFolderList, 0, sizeof(gUserReplayFolderList));
quit = 0;
while(true)
{
if (strStart == NULL)
strStart = ptr;
// if we're encountered string end go on
if(*ptr == ',' || *ptr == ' ' || *ptr == '\0')
{
if (*ptr == '\0')
quit = 1;
*ptr = '\0';
strcpy(gUserReplayFolderList[gNumUserChases++], strStart);
strStart = NULL;
}
ptr++;
if (quit)
break;
}
}
#endif
// decompiled code
@ -103,6 +150,10 @@ void InitInGameCutsceneVariables(void)
gSkipInGameCutscene = 0;
#ifndef PSX
gUserChaseLoaded = -1;
#endif
FreeCutsceneBuffer();
}
@ -255,7 +306,21 @@ void DrawInGameCutscene(void)
#endif
if (gInGameCutsceneActive == 0 && gInGameCutsceneDelay == 0)
{
#ifndef PSX
if(gInGameChaseActive && gUserChaseLoaded != -1 && (CameraCnt - frameStart) < 200)
{
// [A] print user chaser name on screen
char tempStr[80];
sprintf(tempStr, "Getaway is %s", gUserReplayFolderList[gUserChaseLoaded]);
SetTextColour(128, 128, 64);
PrintString(tempStr, 16, 230);
}
#endif
return;
}
tile = (TILE *)current->primptr;
SetTile(tile);
@ -627,10 +692,11 @@ void ReleaseInGameCutscene(void)
replayptr = CutsceneReplayStart;
NumReplayStreams -= NumCutsceneStreams;
NumCutsceneStreams = 0;
CutsceneReplayStart = NULL;
CutsceneStreamIndex = 0;
NumCutsceneStreams = 0;
PreLoadedCutscene = -1;
gHaveInGameCutscene = 0;
gCSDestroyPlayer = 0;
@ -1228,7 +1294,7 @@ int LoadCutsceneToReplayBuffer(int residentCutscene)
return 0;
}
CutsceneStreamIndex = NumReplayStreams;
CutsceneStreamIndex = NumReplayStreams; //rheader->NumReplayStreams;
NumCutsceneStreams = rheader->NumReplayStreams;
CutsceneReplayStart = replayptr;
@ -1264,7 +1330,7 @@ int LoadCutsceneToReplayBuffer(int residentCutscene)
pt += size;
}
NumReplayStreams += rheader->NumReplayStreams;
NumReplayStreams += NumCutsceneStreams;
// copy cutscene cameras and pings
CutsceneCamera = (PLAYBACKCAMERA *)replayptr;
@ -1281,7 +1347,73 @@ int LoadCutsceneToReplayBuffer(int residentCutscene)
return 1;
}
#ifndef PSX
int LoadCutsceneFile(char *filename, int subindex, int userId = -1)
{
gUserChaseLoaded = userId;
int size = LoadfileSeg(filename, gCustomCutsceneBuffer, 0, 0xffff);
if (size != 0)
{
// load into custom buffer
printInfo("Custom chase '%s' loaded\n", filename);
CutsceneBuffer.residentCutscenes[CutsceneBuffer.numResident] = subindex;
CutsceneBuffer.residentPointers[CutsceneBuffer.numResident] = gCustomCutsceneBuffer;
CutsceneBuffer.numResident++;
gCustomCutsceneBuffer += size;
return 1;
}
return 0;
}
int LoadUserCutscene(int subindex, int userId = -1)
{
char customFilename[64];
int userIndex = -1;
if (userId >= 0 && userId < gNumUserChases)
{
// get user chase instantly
sprintf(customFilename, "REPLAYS\\User\\%s\\CUT%d_%d.D2RP", gUserReplayFolderList[userId], gCurrentMissionNumber, subindex);
if (FileExists(customFilename))
userIndex = userId;
}
// if still no valid user replay from input
if (userIndex == -1)
{
// find first valid user replay
for (int i = 0; i < gNumUserChases; i++)
{
sprintf(customFilename, "REPLAYS\\User\\%s\\CUT%d_%d.D2RP", gUserReplayFolderList[i], gCurrentMissionNumber, subindex);
if (FileExists(customFilename))
{
userIndex = i;
break;
}
}
// if it doesn't exist under someone's name, get an anonymous one
if (userIndex == -1)
{
sprintf(customFilename, "REPLAYS\\User\\CUT%d_%d.D2RP", gCurrentMissionNumber, subindex);
// and if it still doesn't exist, let the game handle it
if (!FileExists(customFilename))
return 0;
}
}
return LoadCutsceneFile(customFilename, subindex, userIndex);
}
#endif
// decompiled code
// original method signature:
@ -1323,7 +1455,6 @@ int LoadCutsceneToBuffer(int subindex)
CUTSCENE_HEADER header;
char filename[64];
char customFilename[64];
if (gCurrentMissionNumber < 21)
sprintf(filename, "REPLAYS\\CUT%d.R", gCurrentMissionNumber);
@ -1332,6 +1463,23 @@ int LoadCutsceneToBuffer(int subindex)
printInfo("Loading cutscene '%s' (%d)\n", filename, subindex);
#ifndef PSX
int userId = -1;
// [A] REDRIVER2 PC - custom cutcenes or chases for debugging
if (gNumUserChases)
{
userId = rand() % (gNumUserChases + 1);
// if random decides to have no user chase - get og or replacement one
if (userId == gNumUserChases)
userId = -1;
}
if (LoadUserCutscene(subindex, userId))
return 1;
#endif
if (FileExists(filename))
{
LoadfileSeg(filename, (char *)&header, 0, sizeof(CUTSCENE_HEADER));
@ -1340,25 +1488,7 @@ int LoadCutsceneToBuffer(int subindex)
{
offset = header.data[subindex].offset * 4;
size = header.data[subindex].size;
#ifndef PSX
// [A] REDRIVER2 PC - custom cutcenes or chases for debugging
sprintf(customFilename, "REPLAYS\\CUT%d\\%d.D2RP", gCurrentMissionNumber, subindex);
if (FileExists(customFilename))
{
printInfo("Custom cutscene replay file loaded\n");
size = LoadfileSeg(customFilename, gCustomCutsceneBuffer, 0, 0xffff);
// load into custom buffer
CutsceneBuffer.residentCutscenes[CutsceneBuffer.numResident] = subindex;
CutsceneBuffer.residentPointers[CutsceneBuffer.numResident] = gCustomCutsceneBuffer;
CutsceneBuffer.numResident++;
gCustomCutsceneBuffer += size;
return 1;
}
#endif
if (CutsceneBuffer.bytesFree < size)
{
// load into lead/path AI buffer

View File

@ -1,8 +1,19 @@
#ifndef CUTSCENE_H
#define CUTSCENE_H
#ifndef PSX
#define MAX_USER_REPLAYS 16
extern char gUserReplayFolderList[MAX_USER_REPLAYS][48];
extern int gNumUserChases;
extern void InitUserReplays(const char* str);
#endif
extern CUTSCENE_BUFFER CutsceneBuffer;
extern int NumCutsceneStreams;
extern int gSkipInGameCutscene;
extern int gInGameCutsceneID;
extern int gInGameCutsceneActive;

View File

@ -3658,7 +3658,7 @@ void Setup_Debris(VECTOR *ipos, VECTOR *ispeed, int num_debris, int type)
mydebris->direction.vy = -FIXED(ispeed->vy);
mydebris->direction.vz = FIXED(ispeed->vz);
}
mydebris->type = type & 7;
mydebris->life = 128;
@ -4045,7 +4045,7 @@ void DisplayDebris(DEBRIS *debris, char type)
if (debrisvec.vx >= -10000 && debrisvec.vz >= -10000 && 10000 >= debrisvec.vx && 10000 >= debrisvec.vz)
{
tv = debris_rot_table[debris->type] + (debris->pos >> 3 & 0x1fU);
tv = debris_rot_table[debris->type & 7] + (debris->pos >> 3 & 0x1fU);
v[0].vx = tv->v0.vx + debrisvec.vx;
v[0].vy = tv->v0.vy + debrisvec.vy;
@ -4062,7 +4062,7 @@ void DisplayDebris(DEBRIS *debris, char type)
gte_ldv3(&v[0], &v[1], &v[2]);
gte_rtpt();
if ((uint)type - 1 < 2)
if (type - 1U < 2)
{
poly1 = (POLY_GT4 *)current->primptr;
@ -4317,10 +4317,10 @@ void HandleDebris(void)
lf++;
}
sm = smoke;
i = 0;
for (i = 0; i < MAX_SMOKE; i++)
{
sm = &smoke[i];
do {
if (sm->flags & 2)
{
if (sm->flags & 4)
@ -4364,7 +4364,8 @@ void HandleDebris(void)
}
}
}
else if (sm->flags & 8)
if (sm->flags & 8)
{
// yup, smoke particles are sparks too
DisplaySpark(sm);
@ -4391,6 +4392,7 @@ void HandleDebris(void)
{
sm->flags = 0;
ReleaseSmoke(sm->num);
continue;
}
}
}
@ -4412,10 +4414,7 @@ void HandleDebris(void)
}
}
}
i++;
sm++;
} while (i < MAX_SMOKE);
}
if (pauseflag == 0)
{

View File

@ -15,6 +15,7 @@
#include "SPOOL.H"
#include "MODELS.H"
#include "OBJCOLL.H"
#include "OVERLAY.H"
#include "PRES.H"
#include "SOUND.H"
#include "SYSTEM.H"
@ -150,10 +151,10 @@ int CursorX = 0;
int ClearCameras = 0;
int DirectorMenuActive = 0;
// [D] [T]
void InitDirectorVariables(void)
{
char* pcVar1;
int count;
PlayMode = 0;
@ -1391,11 +1392,20 @@ void ShowIcons(unsigned char* menu, int selected, int x_offset)
// [D] [T]
void ShowReplayOptions(void)
{
if (gInGameCutsceneActive == 0 && quick_replay == 0)
{
ShowReplayMenu();
CameraBar(CameraCnt);
}
if (gInGameCutsceneActive || quick_replay)
return;
// [A] handle sound here
if (DirectorMenuActive) // not a FastForward
PauseSound();
else if(PlayMode != 2 && PlayMode != 3)
UnPauseSound();
if (!gDoOverlays && !DirectorMenuActive)
return;
ShowReplayMenu();
CameraBar(CameraCnt);
}
@ -1454,22 +1464,18 @@ void ShowReplayOptions(void)
// [D] [T]
void ShowReplayMenu(void)
{
unsigned char* menu;
int strobe;
int selected;
if (DirectorMenuActive < 1 && PlayMode != 2 && PlayMode != 3)
{
UnPauseSound();
ShowIcons(menu0, 0, 0);
}
else
{
PauseSound();
selected = CursorX;
if (DirectorMenuActive != 1)
if (DirectorMenuActive == 1)
selected = CursorX;
else
selected = 99;
ShowIcons(menu1, selected, 0);
@ -1481,9 +1487,7 @@ void ShowReplayMenu(void)
{
if (DirectorMenuActive == 2)
{
menu = menu2;
selected = 0;
ShowIcons(menu, CursorY - 1, selected);
ShowIcons(menu2, CursorY - 1, 0);
}
else
{
@ -1494,9 +1498,7 @@ void ShowReplayMenu(void)
{
if (DirectorMenuActive == 2)
{
menu = menu6;
selected = MenuOffset;
ShowIcons(menu, CursorY - 1, selected);
ShowIcons(menu6, CursorY - 1, MenuOffset);
}
else
{
@ -1526,9 +1528,8 @@ void ShowReplayMenu(void)
strobe = 32 - strobe;
SetTextColour((strobe << 3), 0, 0);
PrintString("Auto direct", 100, 0x1e);
PrintString("Auto direct", 100, 30);
}
return;
}
@ -1722,27 +1723,27 @@ void ControlReplay(void)
}
// register pads
if ((padd & 0x8000) != 0 && debounce == 0)
if ((padd & 0x8000) && debounce == 0)
{
move = 2;
debounce = 1;
}
if ((padd & 0x2000) != 0 && debounce == 0)
if ((padd & 0x2000) && debounce == 0)
{
move = 1;
debounce = 1;
}
if ((padd & 0x1000) != 0 && debounce == 0)
if ((padd & 0x1000) && debounce == 0)
{
move = 3;
debounce = 1;
}
if ((padd & 0x4000) != 0 && debounce == 0)
if ((padd & 0x4000) && debounce == 0)
{
move = 4;
debounce = 1;
}
if ((padd & 0x40) != 0 && debounce == 0)
if ((padd & 0x40) && debounce == 0)
{
if (DirectorMenuActive == 0)
pauseflag = 1;
@ -3009,6 +3010,10 @@ int InvalidCamera(int car_num)
int dz;
int numEventModels;
// [A] bug fix of invalid player camera
if (CameraCnt < 3)
return 0;
// check if camera is not too far
if (cameraview != 2)
{

View File

@ -35,6 +35,57 @@ int NumDriver2Curves = 0;
int NumDriver2Straights = 0;
DRIVER2_STRAIGHT *Driver2StraightsPtr = NULL;
#if 0
const short ChicagoBridgeRoads1[] = {
434,
433,
65,
64,
63,
62,
61,
457,
458,
488,
-1,
};
const short ChicagoBridgeRoads2[] = {
336,
319,
297,
284,
260,
254,
222,
-1,
};
const short ChicagoBridgeRoads3[] = {
562,
570,
582,
586,
597,
600,
622,
623,
-1,
};
// [A] Chicago roads
const short* ChicagoBridgeRoads[] = {
// Goose island
ChicagoBridgeRoads1,
// Downtown
ChicagoBridgeRoads2,
// Downtown 2
ChicagoBridgeRoads3,
};
#endif
// [A] custom function for working with roads in very optimized way
int GetSurfaceRoadInfo(DRIVER2_ROAD_INFO* outRoadInfo, int surfId)
{
@ -92,6 +143,39 @@ void ProcessStraightsDriver2Lump(char *lump_file, int lump_size)
{
Getlong((char *)&NumDriver2Straights, lump_file);
Driver2StraightsPtr = (DRIVER2_STRAIGHT *)(lump_file + 4);
#if 0
// [A] patch chicago roads
if (GameLevel == 0)
{
DRIVER2_STRAIGHT* str;
int grp, i, j;
int numLanes;
for (grp = 0; grp < 3; grp++)
{
// don't activate those roads in Caine's Compound
if(grp == 0 && gCurrentMissionNumber == 7)
continue;
i = 0;
while (ChicagoBridgeRoads[grp][i] >= 0)
{
str = GET_STRAIGHT(ChicagoBridgeRoads[grp][i]);
numLanes = ROAD_LANES_COUNT(str);
for (j = 0; j < numLanes; j++)
{
if ((numLanes & 1) && j == numLanes / 2)
continue;
str->AILanes |= 1 << j;
}
i++;
}
}
}
#endif
}

View File

@ -881,8 +881,6 @@ void DrawMapPSX(int* comp_val)
cellx = cellxpos + hloop;
cellz = cellzpos + vloop;
if (rightPlane < 0 &&
leftPlane > 0 &&
backPlane < farClipLimit && // check planes
@ -1854,7 +1852,7 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n)
combo = combointensity;
// transparent object flag
if (pc->flags & 1)
if (pc->flags & PLOT_TRANSPARENT)
combo |= 0x2000000;
i = model->num_polys;
@ -1893,18 +1891,18 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n)
r = rot;
if (pc->flags & 0x6)
if (pc->flags & (PLOT_INV_CULL | PLOT_NO_CULL))
{
if (opz < 0)
r = rot + 32 & 63;
if (pc->flags & 0x4)
if (pc->flags & PLOT_NO_CULL)
opz = 1; // no culling
else
else // PLOT_FRONT_CULL
opz = -opz; // front face
}
if (ptype == 21)
if (ptype == 21 || (pc->flags & PLOT_NO_SHADE))
{
pc->colour = combo & 0x2ffffffU | 0x2c000000;
}
@ -1924,7 +1922,7 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n)
pc->tpage = (*pc->ptexture_pages)[polys->texture_set] << 0x10;
if ((pc->flags & 0x10) == 0) // [A] custom palette flag - for pedestrian heads
if ((pc->flags & PLOT_CUSTOM_PALETTE) == 0) // [A] custom palette flag - for pedestrian heads
pc->clut = (*pc->ptexture_cluts)[polys->texture_set][polys->texture_id] << 0x10;
minZ = pc->scribble[2];
@ -1942,7 +1940,7 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n)
if (maxZ < pc->scribble[0])
diff = pc->scribble[0] - minZ;
if ((n == 0) || ((diff << 2) <= minZ - 350))
if (n == 0 || diff << 2 <= minZ - 350)
{
prims = (POLY_FT4*)pc->primptr;
@ -2057,6 +2055,8 @@ void PlotBuildingModelSubdivNxN(MODEL* model, int rot, _pct* pc, int n)
// [D] [T]
void RenderModel(MODEL* model, MATRIX* matrix, VECTOR* pos, int zBias, int flags, int subdiv, int nrot)
{
int i;
if (matrix != NULL)
{
MATRIX comb;
@ -2074,7 +2074,7 @@ void RenderModel(MODEL* model, MATRIX* matrix, VECTOR* pos, int zBias, int flags
if (zBias > 0)
plotContext.ot += (zBias * 4);
for (int i = 0; i < 8; i++)
for (i = 0; i < 8; i++)
{
plotContext.f4colourTable[i * 4 + 0] = planeColours[i] | 0x2C000000;
plotContext.f4colourTable[i * 4 + 1] = planeColours[0] | 0x2C000000;

View File

@ -30,6 +30,15 @@ extern MATRIX2 CompoundMatrix[64];
#endif
enum PlotFlags
{
PLOT_TRANSPARENT = (1 << 0),
PLOT_INV_CULL = (1 << 1),
PLOT_NO_CULL = (1 << 2),
PLOT_NO_SHADE = (1 << 3),
PLOT_CUSTOM_PALETTE = (1 << 4),
};
extern void* model_tile_ptrs[MAX_DRAWN_TILES];
extern int units_across_halved;

View File

@ -264,10 +264,10 @@ void HandleDrivingGames(void)
gPlayerScore.items++;
else
gPlayerScore.P2items++;
}
gTrailblazerConeIndex += i + 1;
gTrailblazerPrevConeDelay = 10;
gTrailblazerConeIndex += i + 1;
gTrailblazerPrevConeDelay = 10;
}
// reset side
for(j = 0; j < 2; j++)

View File

@ -6,6 +6,7 @@
#include "SYSTEM.H"
#include "PRES.H"
#include "PAUSE.H"
#include "SOUND.H"
#undef v0
@ -171,7 +172,7 @@ void FadeInHiresScreen(char *filename)
DrawSync(0);
setRECT16(&rect, 640, 0, 320, 511);
LoadImage(&rect, (u_long*)&_overlay_buffer[512]);
LoadImage(&rect, (u_long*)&_overlay_buffer[524]);
DrawSync(0);
SetDispMask(1);
@ -199,8 +200,6 @@ void FadeInHiresScreen(char *filename)
setRGB0(prim, 128, 128, 128);
}
// UNCERTAIN CODE
// LEARN TO DECOMPILE MIPS FIRST
addPrim(&ot, prim);
addPrim(&ot, poly);
poly++; prim++;
@ -218,6 +217,158 @@ void FadeInHiresScreen(char *filename)
DrawSync(0);
}
#define GALLERY_IMAGES 24
// [A] displays bonus gallery
void ShowBonusGallery()
{
char filename[64];
int currentImage;
DISPENV disp;
DRAWENV draw;
SPRT prims[6];
POLY_FT3 nulls[6];
RECT16 rect;
OTTYPE ot;
POLY_FT3 *poly;
SPRT *prim;
POLYCOORD *pc;
DrawSync(0);
VSync(0);
SetDispMask(0);
ResetGraph(3);
setRECT16(&rect, 0, 0, 512, 512);
ClearImage2(&rect, 0, 0, 0);
DrawSync(0);
setRECT16(&rect, 512, 0, 512, 512);
ClearImage2(&rect, 0, 0, 0);
DrawSync(0);
poly = nulls;
pc = polycoords;
prim = prims;
// prepare polygons
for(int i = 0; i < 6; i++)
{
// set primitive
setSprt(prim);
setUV0(prim, 0, 0);
setClut(prim, 640, 511);
setXY0(prim, pc->x, pc->y);
setWH(prim, pc->w, pc->h);
// set poly
setPolyFT3(poly);
setXY3(poly, -1,-1,-1,-1,-1,-1);
setTPage(poly, 1, 0, pc->u, pc->v);
prim++;
poly++;
pc++;
}
SetupDefDrawEnv(&draw, 0, 0, 640, 512);
SetupDefDispEnv(&disp, 0, 0, 640, 512);
VSync(0);
PutDispEnv(&disp);
PutDrawEnv(&draw);
currentImage = 0;
// draw image cycle
while(currentImage <= GALLERY_IMAGES)
{
if(currentImage == 0)
sprintf(filename, "GFX\\GAL\\INTRO.TIM");
else
sprintf(filename, "GFX\\GAL\\IMG%d.TIM", currentImage-1);
LoadfileSeg(filename, _other_buffer, 20, 0x4ff80);
LoadClut((u_long*)_other_buffer, 640, 511);
DrawSync(0);
setRECT16(&rect, 640, 0, 320, 511);
LoadImage(&rect, (u_long*)&_other_buffer[524]);
DrawSync(0);
SetDispMask(1);
// now draw image
DrawSync(0);
VSync(0);
PutDispEnv(&disp);
PutDrawEnv(&draw);
ClearOTagR((u_long*)&ot, 1);
poly = nulls;
prim = prims;
for (int i = 0; i < 6; i++)
{
setRGB0(prim, 128, 128, 128);
addPrim(&ot, prim);
addPrim(&ot, poly);
poly++; prim++;
}
DrawOTag((u_long*)&ot);
#ifndef PSX
Emulator_EndScene();
#endif
// wait for user input
do {
ReadControllers();
VSync(-1);
if(Pads[0].dirnew & 0x8000)
{
currentImage--;
if (currentImage < 0)
{
FESound(1);
currentImage = 0;
}
else
{
FESound(3);
break;
}
}
if(Pads[0].dirnew & 0x2000)
{
FESound(3);
currentImage++;
break;
}
if(Pads[0].dirnew & 0x10)
{
FESound(0);
currentImage = GALLERY_IMAGES+1; // quit
break;
}
} while (true);
}
DrawSync(0);
}
// decompiled code
@ -395,8 +546,6 @@ void SetupDefDrawEnv(DRAWENV *env, int x, int y, int w, int h)
// [D] [T]
void SetupDefDispEnv(DISPENV *env, int x, int y, int w, int h)
{
short framey;
if (h < 257)
{
SetDefDispEnv(env, x, y, w, 256);

View File

@ -16,5 +16,6 @@ extern void SetPleaseWait(char *buffer); // 0x000448CC
extern void CheckForCorrectDisc(int disc); // 0x00044A40
extern void ShowBonusGallery();
#endif

View File

@ -33,28 +33,34 @@
// TODO: put more meaning into those arrays
int ElTrainData[83] = {
6, // train count (WRONG)
6, // train count
// train 1 (n 1)
80, 130, 32768, 336284, -220364, 283420, PATH_NODE_STATION,
80, 130, 0x8000, // speed 1, 2, start direction
336284, -220364, 283420, PATH_NODE_STATION,
-204500, -158924, 247580, -123084, 188624, -158924, 73520, -138444, 17200, -124148, -39120, PATH_NODE_STATION,
-109276, -82131, -80103, -17628, -203568, -124712, -39728, -265000, 129620, -386012, PATH_NODE_WRAP,
// train 2 (n 31)
80, 130, 0, -158928, 189219, -123684, 246995, PATH_NODE_CYCLE,
80, 130, 0,
-158928, 189219, -123684, 246995, PATH_NODE_CYCLE,
// train 3 (n 39)
0, 90, 32768, 188402, -425768, 354291, PATH_NODE_WRAP,
0, 90, 0x8000,
188402, -425768, 354291, PATH_NODE_WRAP,
// train 4 (n 46)
0, 90, 32768, 354291, -425168, 188402, PATH_NODE_WRAP,
0, 90, 0x8000,
354291, -425168, 188402, PATH_NODE_WRAP,
// train 4 (n 53)
60, 110, 0, -386012, 130215, -264404, -39132, -124688, 16619, -139048, 72943, -159520, 282863, PATH_NODE_STATION,
// train 5 (n 53)
60, 110, 0,
-386012, 130215, -264404, -39132, -124688, 16619, -139048, 72943, -159520, 282863, PATH_NODE_STATION,
-204991, -220964, 336284, PATH_NODE_WRAP,
// train 5 (n 71)
70, 120, 0, -82719, -39712, PATH_NODE_STATION,
// train 6 (n 71)
70, 120, 0,
-82719, -39712, PATH_NODE_STATION,
-115487, -124120, -202968,-18216, -80683, PATH_NODE_CYCLE
};
@ -79,15 +85,42 @@ int HavanaMiniData[4] = {
};
int LiftingBridges[55] = {
8, -182784, -175616, -168448,
8, // bridge count
// 1
-182784, -175616, -168448,
7, -227328, -162304, -141824, -121344, -100864, -80384, -59904,
256, -312832, -305664, -298496,
1, 324096, -311808, -304640, -297472,
1, 247296, -256512, -249344, -242176,
1, 247296, -262656, -255488, -248320,
1, 324096, 32768, 170496, 177664, 184832,
1, -271360, -12800, -5632, 1536,
5, -162304, -102912, -82432, -61952, -39936, -6656, 512, 7680,
0x100, // goose island start
// 2
-312832, -305664, -298496,
1, 324096,
// 3
-311808, -304640, -297472,
1, 247296,
// 4
-256512, -249344, -242176,
1, 247296,
// 5
-262656, -255488, -248320,
1, 324096,
0x8000, // goose island end
// 6
170496, 177664, 184832,
1, -271360,
// 7
-12800, -5632, 1536,
5, -162304, -102912, -82432, -61952, -39936,
// 8
-6656, 512, 7680,
3, 4137, 27648, 128000
};
@ -1157,16 +1190,17 @@ void SetUpEvents(int full)
int timeOffset;
cameraEventsActive = 1;
if (p[0] == 0x8000)
{
direction = true;
p++;
}
else if (p[0] == 0x100)
// goose island bridges start/end?
if (p[0] == 0x100)
{
firstMissionEvent = &event[cEvents];
p++;
}
else if (p[0] == 0x8000)
{
direction = true;
p++;
}
evt = &event[cEvents];
@ -1195,7 +1229,7 @@ void SetUpEvents(int full)
{
if (direction)
{
evt[i].flags = 1;
evt[i].flags = 0x1;
evt[i].position.vx = *p;
}
else
@ -2313,7 +2347,7 @@ void StepPathEvent(EVENT* ev)
centre.z = turn[1] - 2048;
if (ev->flags & 0x400)
speed = *ev->data;
speed = ev->data[0];
offset.x = (ev->position.vz - centre.z) * speed / 2048;
offset.z = (centre.x - ev->position.vx) * speed / 2048;
@ -3282,7 +3316,7 @@ void DrawFerrisWheel(MATRIX* matrix, VECTOR* pos)
if (chicagoDoor[2].model == -1)
return;
RenderModel(modelpointers[chicagoDoor[2].model], matrix, pos, 0, 4, 1, 0);
RenderModel(modelpointers[chicagoDoor[2].model], matrix, pos, 0, PLOT_NO_CULL, 1, 0);
if (chicagoDoor[2].model != -1)
RenderModel(modelpointers[chicagoDoor[2].initialRotation], NULL, NULL, 0, 0, 1, 0);
@ -3291,7 +3325,7 @@ void DrawFerrisWheel(MATRIX* matrix, VECTOR* pos)
matrix->m[1][0] = -matrix->m[1][0];
matrix->m[2][0] = -matrix->m[2][0];
RenderModel(modelpointers[chicagoDoor[2].model], matrix, pos, 0, 4, 1, 0);
RenderModel(modelpointers[chicagoDoor[2].model], matrix, pos, 0, PLOT_NO_CULL, 1, 0);
if (chicagoDoor[2].minSpeed == -1)
return;
@ -3870,7 +3904,7 @@ void DrawEvents(int camera)
SetupPlaneColours(0x00464a40);
RenderModel(modelpointers[ev->model], &matrix, &pos, 400, 2, 1, ev->rotation >> 6);
RenderModel(modelpointers[ev->model], &matrix, &pos, 400, PLOT_INV_CULL, 1, ev->rotation >> 6);
}
else
{

View File

@ -0,0 +1,540 @@
u_char fmvFont[] = {
0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,
0x00, 0x00, 0x51, 0x46, 0x08, 0x21, 0x5A, 0x6B, 0x63, 0x0C, 0xBD, 0x77, 0xFF, 0x7F, 0x00, 0x00, 0xD6, 0x5A, 0xCD, 0x35,
0xA5, 0x14, 0xDE, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x66, 0x26, 0x00, 0x68, 0x66, 0x08, 0x00, 0x90, 0x6B, 0x2B, 0x00,
0x68, 0x66, 0x08, 0x00, 0x62, 0x66, 0x26, 0x00, 0x62, 0x66, 0x06, 0x52, 0xB6, 0x01, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66,
0x09, 0x00, 0x90, 0x66, 0x00, 0x68, 0x88, 0x16, 0x00, 0x68, 0x08, 0x00, 0x62, 0x86, 0x90, 0x66, 0x06, 0x66, 0x03, 0x66,
0x00, 0x39, 0x66, 0x01, 0x00, 0x69, 0x66, 0x93, 0x00, 0x52, 0x66, 0x08, 0x00, 0x69, 0x66, 0x93, 0x00, 0x90, 0x6B, 0x93,
0x00, 0x68, 0x66, 0x26, 0x00, 0x63, 0x83, 0x86, 0x00, 0x69, 0x06, 0x68, 0x08, 0x61, 0x06, 0x66, 0x08, 0x66, 0x00, 0x69,
0x03, 0x61, 0x09, 0x66, 0x01, 0x61, 0x09, 0x60, 0x66, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x62, 0x06, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x6B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x90, 0x66, 0x96, 0x00,
0x68, 0x53, 0x16, 0x00, 0x6A, 0x86, 0x56, 0x00, 0x68, 0x55, 0x86, 0x00, 0x6A, 0x16, 0x41, 0x00, 0x62, 0x16, 0x09, 0x6B,
0x68, 0xA6, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66, 0x01, 0x00, 0x90, 0x66, 0x00, 0x68, 0xB8, 0x96, 0x00, 0x68, 0x08, 0x00,
0x6A, 0x66, 0x90, 0x66, 0x06, 0x66, 0x06, 0x66, 0x00, 0x6B, 0x68, 0x96, 0x00, 0x69, 0x36, 0x66, 0x00, 0x6B, 0x68, 0x96,
0x00, 0x69, 0x36, 0x56, 0x00, 0x6A, 0x86, 0x56, 0x00, 0x89, 0x66, 0x49, 0x00, 0x68, 0x88, 0x86, 0x00, 0x69, 0xA6, 0x6B,
0x09, 0x6A, 0x26, 0x66, 0x28, 0x86, 0x00, 0x60, 0x46, 0x66, 0x00, 0x68, 0x03, 0x63, 0x0A, 0x90, 0x69, 0x86, 0x00, 0x00,
0x00, 0x00, 0x00, 0x62, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x06, 0x00, 0x00, 0x00, 0x00, 0x90, 0x36, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x10, 0x66, 0x86, 0x00, 0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x00, 0x68, 0x88, 0x86, 0x00,
0x62, 0x26, 0x00, 0x00, 0x62, 0x26, 0x00, 0x66, 0x69, 0x26, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66, 0x09, 0x00, 0x90, 0x66,
0x00, 0x68, 0x66, 0x06, 0x00, 0x68, 0x08, 0x00, 0x62, 0x66, 0x8A, 0x66, 0x06, 0x66, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96,
0x00, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x61, 0x96, 0x66, 0x00, 0x62, 0x16, 0x66, 0x00, 0x90, 0x66, 0x00,
0x00, 0x68, 0x88, 0x36, 0x00, 0x62, 0x26, 0x66, 0x09, 0x62, 0x96, 0x66, 0x96, 0x86, 0x00, 0x30, 0x16, 0x16, 0x00, 0x62,
0x96, 0xB6, 0x00, 0x00, 0x64, 0x96, 0x00, 0x90, 0x83, 0x02, 0x00, 0x62, 0x86, 0xA8, 0x00, 0x1A, 0x18, 0x0A, 0x89, 0x68,
0x06, 0x90, 0x88, 0x01, 0x00, 0x5A, 0x56, 0x09, 0x10, 0x18, 0x98, 0x00, 0x30, 0x66, 0x86, 0x00, 0x68, 0x88, 0x86, 0x00,
0x62, 0x96, 0x66, 0x00, 0x68, 0x88, 0x86, 0x00, 0x62, 0xA6, 0x00, 0x00, 0x62, 0x26, 0x00, 0x66, 0x69, 0x26, 0x00, 0x69,
0x96, 0x66, 0x00, 0x66, 0x09, 0x00, 0x90, 0x66, 0x00, 0x68, 0x66, 0x03, 0x00, 0x68, 0x08, 0x00, 0x6A, 0x66, 0xB2, 0x66,
0x06, 0x66, 0x16, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x96, 0x66,
0x00, 0x62, 0x16, 0x88, 0x00, 0x90, 0x66, 0x00, 0x00, 0x68, 0x88, 0x86, 0x00, 0x64, 0x26, 0x66, 0x09, 0x60, 0x86, 0x66,
0x96, 0x16, 0x00, 0x90, 0x66, 0x96, 0x00, 0x60, 0x66, 0x96, 0x00, 0x00, 0x69, 0x46, 0x00, 0x69, 0x68, 0xA6, 0x00, 0x6A,
0x86, 0x86, 0x00, 0x6B, 0x68, 0x05, 0x66, 0x68, 0x06, 0x6A, 0x86, 0x86, 0x00, 0x84, 0x36, 0x09, 0x69, 0x53, 0x96, 0x00,
0x30, 0x66, 0x36, 0x00, 0x68, 0x55, 0x96, 0x00, 0x6A, 0x26, 0x00, 0x00, 0x68, 0x88, 0x86, 0x00, 0x62, 0x86, 0x09, 0x00,
0x62, 0x86, 0x02, 0x66, 0x09, 0x00, 0x00, 0x69, 0x86, 0x66, 0x00, 0x66, 0x09, 0x00, 0x90, 0x66, 0x00, 0x68, 0x66, 0x09,
0x00, 0x63, 0x08, 0x00, 0x62, 0x66, 0x69, 0x66, 0x06, 0x66, 0x36, 0x66, 0x00, 0x66, 0x61, 0x96, 0x00, 0x69, 0x96, 0x66,
0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x36, 0x96, 0x00, 0x30, 0x66, 0x09, 0x00, 0x90, 0x66, 0x00, 0x00, 0x68, 0x88, 0x86,
0x00, 0x60, 0x96, 0x66, 0x02, 0x60, 0x86, 0x66, 0x36, 0x96, 0x00, 0x20, 0x66, 0x46, 0x00, 0x10, 0x66, 0xA6, 0x00, 0x00,
0x68, 0x03, 0x00, 0x69, 0x61, 0x26, 0x00, 0x62, 0x96, 0x86, 0x00, 0x66, 0x69, 0x06, 0x66, 0x69, 0x06, 0x6A, 0x96, 0x86,
0x00, 0x90, 0x86, 0x00, 0x69, 0x88, 0x96, 0x00, 0x60, 0x96, 0x66, 0x00, 0x68, 0x65, 0xA3, 0x00, 0x62, 0x26, 0x00, 0x00,
0x68, 0x88, 0x86, 0x00, 0x62, 0x86, 0x08, 0x00, 0x62, 0x86, 0x01, 0x66, 0x21, 0x02, 0x00, 0x69, 0x36, 0x66, 0x00, 0x66,
0x09, 0x00, 0x90, 0x66, 0x00, 0x68, 0x66, 0x09, 0x00, 0x68, 0x08, 0x00, 0x62, 0x63, 0x66, 0x63, 0x06, 0x66, 0x63, 0x66,
0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x86, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x56, 0x9B, 0x00, 0xA0, 0x6B, 0xA5,
0x00, 0x90, 0x66, 0x00, 0x00, 0x68, 0x88, 0x86, 0x00, 0x60, 0x86, 0x66, 0x02, 0x80, 0x66, 0x56, 0x66, 0x26, 0x00, 0x90,
0x66, 0x06, 0x00, 0x20, 0x66, 0x03, 0x00, 0x00, 0x66, 0x01, 0x00, 0x89, 0x61, 0x26, 0x00, 0x62, 0x96, 0x86, 0x00, 0x66,
0x69, 0x06, 0x66, 0x69, 0x06, 0x62, 0x96, 0x86, 0x00, 0x90, 0x86, 0x00, 0x69, 0x38, 0x96, 0x00, 0x6A, 0x86, 0x66, 0x0A,
0x68, 0x88, 0x86, 0x00, 0x62, 0x26, 0x22, 0x00, 0x68, 0x88, 0x86, 0x00, 0x62, 0x26, 0x00, 0x00, 0x62, 0x26, 0x00, 0x66,
0x68, 0x26, 0x00, 0x69, 0x16, 0x66, 0x00, 0x66, 0x09, 0x20, 0x92, 0x66, 0x00, 0x68, 0x66, 0x08, 0x00, 0x68, 0x08, 0x00,
0x62, 0x61, 0x66, 0x68, 0x06, 0x66, 0x61, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x66, 0x95, 0x00, 0x66, 0x69, 0x96,
0x00, 0x69, 0x96, 0xB6, 0x00, 0x20, 0xB9, 0xB6, 0x00, 0x90, 0x66, 0x00, 0x00, 0x68, 0x88, 0x86, 0x00, 0x80, 0x86, 0x66,
0x00, 0x80, 0x66, 0x86, 0x66, 0x26, 0x00, 0x80, 0x66, 0x96, 0x00, 0x00, 0x66, 0x09, 0x00, 0x90, 0x66, 0x02, 0x00, 0x10,
0x66, 0x26, 0x00, 0x62, 0x96, 0x36, 0x00, 0x66, 0xA9, 0x02, 0x66, 0x69, 0x06, 0x6A, 0x66, 0x86, 0x00, 0x90, 0x86, 0x00,
0x69, 0x88, 0x96, 0x00, 0x62, 0x86, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x00, 0x68, 0x88, 0x86, 0x00,
0x62, 0x26, 0x00, 0x00, 0x62, 0x26, 0x00, 0x66, 0x61, 0x26, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66, 0x09, 0x62, 0x96, 0x66,
0x00, 0x68, 0x66, 0x06, 0x00, 0x68, 0x08, 0x00, 0x62, 0x39, 0x66, 0x69, 0x06, 0x66, 0x69, 0x66, 0x00, 0x66, 0x69, 0x96,
0x00, 0x69, 0x06, 0x00, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x96, 0x66, 0x00, 0x62, 0x96, 0x66, 0x02, 0x10, 0x66, 0x00,
0x00, 0x63, 0x88, 0x86, 0x00, 0x80, 0x36, 0x66, 0x00, 0x90, 0x66, 0x88, 0x66, 0x06, 0x00, 0x50, 0xB6, 0x16, 0x00, 0x00,
0x66, 0x09, 0x00, 0x10, 0x56, 0x00, 0x00, 0x61, 0x61, 0x26, 0x00, 0x62, 0x96, 0x86, 0x00, 0x66, 0x69, 0x06, 0x66, 0x69,
0x06, 0x62, 0x16, 0x18, 0x00, 0x90, 0x86, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x06, 0x66, 0x09, 0x68, 0x88, 0x86, 0x00,
0x62, 0x96, 0x66, 0x00, 0x68, 0x88, 0x86, 0x00, 0x62, 0x26, 0x00, 0x00, 0x62, 0x26, 0x00, 0x66, 0x69, 0x26, 0x00, 0x69,
0x96, 0x66, 0x00, 0x66, 0x09, 0x62, 0x96, 0x66, 0x00, 0x68, 0x68, 0x96, 0x00, 0x68, 0x08, 0x00, 0x62, 0x19, 0x66, 0x62,
0x06, 0x66, 0x64, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x06, 0x00, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x96, 0x66,
0x00, 0x62, 0x26, 0x66, 0x02, 0x90, 0x66, 0x00, 0x00, 0x68, 0x88, 0x86, 0x00, 0x10, 0x66, 0x36, 0x00, 0x90, 0x66, 0x98,
0x66, 0x06, 0x00, 0x62, 0x95, 0x56, 0x00, 0x00, 0x66, 0x09, 0x00, 0x50, 0x16, 0x00, 0x00, 0x68, 0x69, 0x26, 0x00, 0x62,
0x96, 0x86, 0x00, 0x66, 0x61, 0x06, 0x66, 0x69, 0x06, 0x62, 0x96, 0x86, 0x00, 0x90, 0x86, 0x00, 0x69, 0x88, 0x96, 0x00,
0x69, 0x06, 0x66, 0x09, 0x68, 0x53, 0x16, 0x00, 0x6A, 0x16, 0x66, 0x00, 0x68, 0x53, 0x16, 0x00, 0x62, 0x16, 0x49, 0x00,
0x62, 0x26, 0x00, 0x66, 0x61, 0x26, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66, 0x09, 0x62, 0x16, 0x66, 0x00, 0x68, 0x38, 0x16,
0x00, 0x68, 0x93, 0x02, 0x62, 0x99, 0x36, 0x6A, 0x06, 0x66, 0x30, 0x66, 0x00, 0x66, 0x61, 0x96, 0x00, 0x69, 0x06, 0x00,
0x00, 0x66, 0x61, 0x96, 0x00, 0x69, 0x96, 0x66, 0x00, 0x62, 0x96, 0x66, 0x0A, 0x90, 0x66, 0x00, 0x00, 0x63, 0x33, 0x86,
0x00, 0x90, 0x66, 0x86, 0x00, 0x90, 0x66, 0x98, 0x66, 0x08, 0x00, 0x61, 0xA8, 0x66, 0x02, 0x00, 0x66, 0x09, 0x00, 0x62,
0x86, 0x99, 0x00, 0x68, 0x61, 0x26, 0x00, 0x6A, 0x86, 0x86, 0x00, 0x66, 0x61, 0x06, 0x66, 0x61, 0x06, 0x62, 0x16, 0x86,
0x00, 0x90, 0x86, 0x00, 0x69, 0x83, 0x96, 0x00, 0x68, 0x08, 0x63, 0x03, 0x68, 0x66, 0x48, 0x00, 0x80, 0x66, 0x16, 0x00,
0x63, 0x66, 0x03, 0x00, 0x6A, 0x66, 0x26, 0x00, 0x62, 0x26, 0x00, 0x61, 0x86, 0x26, 0x00, 0x69, 0x96, 0x66, 0x00, 0x66,
0x09, 0x80, 0x66, 0x96, 0x00, 0x68, 0x18, 0x56, 0x00, 0x68, 0x66, 0x09, 0x62, 0x29, 0x16, 0x62, 0x06, 0x66, 0x10, 0x66,
0x00, 0x61, 0x66, 0x03, 0x00, 0x69, 0x06, 0x00, 0x00, 0x69, 0x66, 0x03, 0x00, 0x69, 0x26, 0x66, 0x02, 0x80, 0x66, 0x16,
0x00, 0x90, 0x66, 0x00, 0x00, 0x52, 0x66, 0xA5, 0x00, 0x90, 0x66, 0x16, 0x00, 0x20, 0x66, 0x28, 0x66, 0x08, 0x00, 0x63,
0x02, 0x63, 0x01, 0x00, 0x66, 0x09, 0x00, 0x62, 0x66, 0x66, 0x00, 0x62, 0x56, 0xA6, 0x00, 0x62, 0x53, 0x95, 0x00, 0x59,
0x56, 0x02, 0x61, 0x55, 0x06, 0x10, 0x66, 0xA3, 0x00, 0x90, 0x86, 0x00, 0x5A, 0x55, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x93,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x90, 0x59, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x08, 0x00, 0x00, 0x69, 0x08, 0x90, 0x36,
0x00, 0x66, 0x02, 0x00, 0x00, 0x66, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x29, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x8A, 0x66, 0xA8, 0x00, 0x20, 0x66, 0x00, 0x52, 0xB6, 0x09, 0x00, 0x10, 0x66, 0xA8, 0x00, 0x00,
0x65, 0x16, 0x00, 0x66, 0x66, 0x46, 0x00, 0x10, 0x66, 0xA8, 0x00, 0x68, 0x66, 0x26, 0x00, 0x80, 0x66, 0xA8, 0x00, 0x39,
0xB6, 0x01, 0x00, 0x69, 0x03, 0x80, 0x66, 0x01, 0x00, 0x69, 0x08, 0x10, 0x86, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x69, 0x08, 0x00, 0x00, 0x92, 0x09, 0x20, 0x29, 0x00, 0x66, 0x02, 0x00, 0x00, 0x66, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x33, 0x86, 0x00, 0xBA, 0x66, 0x00, 0x6B,
0x68, 0x06, 0x00, 0x69, 0x33, 0x86, 0x00, 0x20, 0x66, 0x96, 0x00, 0x66, 0x91, 0x09, 0x00, 0x69, 0x36, 0x16, 0x00, 0x92,
0x68, 0x26, 0x00, 0x69, 0x36, 0x86, 0x00, 0x6B, 0x68, 0x96, 0x00, 0x69, 0x08, 0x69, 0x38, 0x96, 0x00, 0x92, 0x09, 0xB0,
0x11, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x85, 0x08, 0x00, 0x89, 0x01, 0x90, 0x18, 0x00, 0x66, 0x89, 0x08,
0x00, 0x66, 0x02, 0x8A, 0x18, 0x98, 0x31, 0x02, 0x89, 0x88, 0x01, 0x00, 0x10, 0x88, 0x09, 0x00, 0x89, 0x81, 0x01, 0x00,
0x90, 0x98, 0x13, 0x00, 0x8A, 0x18, 0xA8, 0x00, 0x20, 0x88, 0x02, 0x00, 0x59, 0x36, 0x01, 0x8A, 0x98, 0x98, 0x00, 0x89,
0x01, 0x38, 0x0A, 0x88, 0x90, 0x98, 0x80, 0x08, 0x81, 0x92, 0x98, 0x00, 0x89, 0x09, 0x81, 0x0A, 0x82, 0x88, 0x08, 0x00,
0x68, 0x83, 0x86, 0x00, 0x3A, 0x66, 0x00, 0x66, 0x69, 0x26, 0x00, 0x69, 0x88, 0x86, 0x00, 0x90, 0x66, 0x96, 0x00, 0x66,
0x02, 0x00, 0x00, 0x69, 0x86, 0x86, 0x00, 0x00, 0x61, 0x05, 0x00, 0x69, 0x86, 0x86, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69,
0x08, 0x69, 0x89, 0x96, 0x00, 0x69, 0x08, 0x6A, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x33, 0x96, 0x00,
0x69, 0x08, 0x90, 0x86, 0x00, 0x66, 0x63, 0x03, 0x00, 0x66, 0x02, 0x62, 0x36, 0x66, 0x63, 0x06, 0x69, 0x55, 0x96, 0x00,
0x69, 0x53, 0x16, 0x00, 0x69, 0x35, 0x16, 0x00, 0x62, 0x36, 0x86, 0x00, 0x62, 0xB6, 0x86, 0x00, 0x6A, 0x35, 0xA6, 0x00,
0x32, 0x86, 0x02, 0x62, 0x96, 0x86, 0x00, 0x62, 0x26, 0x66, 0x00, 0x68, 0x82, 0x86, 0x62, 0x03, 0x69, 0x88, 0x46, 0x00,
0x6A, 0x03, 0x66, 0x00, 0x89, 0x65, 0x05, 0x00, 0x68, 0x88, 0x86, 0x00, 0x90, 0x66, 0x00, 0x66, 0x61, 0x26, 0x00, 0x69,
0x38, 0x86, 0x00, 0x80, 0x66, 0x96, 0x00, 0x66, 0x99, 0x02, 0x00, 0x69, 0x96, 0xA9, 0x00, 0x00, 0x63, 0x08, 0x00, 0x69,
0x86, 0x86, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x08, 0x69, 0x89, 0x96, 0x00, 0x69, 0x08, 0x92, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x90, 0x86, 0x00, 0x66, 0x66, 0x09, 0x00, 0x66, 0x02, 0x62,
0x26, 0x66, 0x62, 0x06, 0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x62, 0x96, 0x86, 0x00,
0x62, 0x96, 0x86, 0x00, 0x62, 0x88, 0x26, 0x00, 0x80, 0x96, 0x00, 0x62, 0x96, 0x86, 0x00, 0x6A, 0x26, 0x56, 0x00, 0x61,
0x39, 0x86, 0x69, 0x01, 0x64, 0x6B, 0x03, 0x00, 0x50, 0x26, 0x36, 0x00, 0x00, 0x68, 0x01, 0x00, 0x68, 0x83, 0x86, 0x00,
0x90, 0x66, 0x00, 0x00, 0x61, 0x0B, 0x00, 0x00, 0x5A, 0x96, 0x00, 0x60, 0x63, 0x96, 0x00, 0x66, 0x66, 0x46, 0x00, 0x69,
0x66, 0x96, 0x00, 0xA0, 0x66, 0x09, 0x00, 0x54, 0x36, 0x96, 0x00, 0x66, 0x61, 0x96, 0x00, 0x69, 0x08, 0x92, 0x52, 0x96,
0x00, 0x69, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x88, 0x16, 0x00, 0x69, 0x08, 0x90, 0x86,
0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x02, 0x62, 0x26, 0x66, 0x62, 0x06, 0x61, 0x83, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00,
0x69, 0x88, 0x96, 0x00, 0x62, 0x96, 0x86, 0x00, 0x62, 0x96, 0x86, 0x00, 0x62, 0x85, 0xA8, 0x00, 0x80, 0x96, 0x00, 0x62,
0x96, 0x86, 0x00, 0x60, 0x16, 0x86, 0x00, 0x69, 0x61, 0x66, 0x61, 0x01, 0x80, 0x66, 0x09, 0x00, 0x80, 0x86, 0x16, 0x00,
0x40, 0x66, 0x0A, 0x00, 0x68, 0x88, 0x86, 0x00, 0x90, 0x66, 0x00, 0x40, 0x66, 0x09, 0x00, 0x00, 0x69, 0xA3, 0x00, 0x62,
0x68, 0x16, 0x00, 0x88, 0x69, 0xA6, 0x00, 0x69, 0x36, 0x86, 0x00, 0x10, 0x66, 0x04, 0x00, 0x30, 0x56, 0xA3, 0x00, 0x61,
0x66, 0x96, 0x00, 0x69, 0x08, 0x00, 0x61, 0x08, 0x00, 0x69, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x90, 0x86, 0x00, 0x66, 0xB6, 0x00, 0x00, 0x66, 0x02, 0x62, 0x26, 0x66, 0x62, 0x06,
0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x62, 0x96, 0x86, 0x00, 0x62, 0x06, 0x00, 0x00,
0x10, 0x66, 0x01, 0x00, 0x80, 0x96, 0x00, 0x62, 0x96, 0x86, 0x00, 0x30, 0x86, 0x16, 0x00, 0x62, 0x63, 0x66, 0x63, 0x02,
0x90, 0x66, 0x02, 0x00, 0x90, 0x66, 0x96, 0x00, 0x10, 0x36, 0x00, 0x00, 0x68, 0x88, 0x86, 0x00, 0x90, 0x66, 0x00, 0x10,
0xB6, 0x00, 0x00, 0x92, 0x89, 0x86, 0x00, 0x61, 0x69, 0x96, 0x00, 0x99, 0x61, 0x26, 0x00, 0x69, 0x86, 0x86, 0x00, 0x80,
0x36, 0x00, 0x00, 0x69, 0x86, 0x86, 0x00, 0x89, 0x69, 0x96, 0x00, 0x69, 0x08, 0x40, 0x66, 0x0A, 0x00, 0x69, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x90, 0x86, 0x00, 0x66, 0x66, 0x09,
0x00, 0x66, 0x0A, 0x62, 0x26, 0x66, 0x62, 0x06, 0x69, 0x88, 0x96, 0x00, 0x69, 0x83, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00,
0x62, 0x96, 0x86, 0x00, 0x62, 0x06, 0x00, 0x00, 0x92, 0x68, 0x96, 0x00, 0x80, 0x16, 0x00, 0x62, 0x96, 0x86, 0x00, 0x80,
0xB6, 0x96, 0x00, 0x64, 0x66, 0x66, 0x66, 0x04, 0x30, 0x66, 0x09, 0x00, 0x20, 0x66, 0x26, 0x00, 0x30, 0x96, 0x00, 0x00,
0x68, 0x88, 0x86, 0x00, 0x90, 0x66, 0x00, 0xB0, 0x16, 0x00, 0x00, 0x69, 0x88, 0x86, 0x00, 0x63, 0x6A, 0x96, 0x00, 0x66,
0x68, 0x26, 0x00, 0x69, 0x86, 0x86, 0x00, 0x60, 0x16, 0x00, 0x00, 0x69, 0x86, 0x86, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69,
0x08, 0x90, 0x86, 0x00, 0x00, 0x69, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x88, 0x16, 0x00,
0x69, 0x08, 0x90, 0x36, 0x00, 0x66, 0x63, 0x03, 0x00, 0x66, 0x02, 0x62, 0x26, 0x66, 0x62, 0x06, 0x69, 0x88, 0x96, 0x00,
0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x6A, 0x96, 0x86, 0x00, 0x62, 0x06, 0x00, 0x00, 0x69, 0x88, 0x96, 0x00,
0x80, 0x96, 0x00, 0x62, 0x96, 0x86, 0x00, 0x90, 0x66, 0x26, 0x00, 0x60, 0x66, 0x61, 0x66, 0x00, 0x64, 0x66, 0x03, 0x00,
0x00, 0x66, 0x06, 0x00, 0x69, 0x46, 0x00, 0x00, 0x63, 0x38, 0x86, 0x00, 0x90, 0x66, 0x00, 0x69, 0x46, 0x00, 0x00, 0x69,
0x88, 0x86, 0x00, 0x66, 0x66, 0x66, 0x08, 0x66, 0x68, 0x26, 0x00, 0x69, 0x86, 0x86, 0x00, 0x62, 0x26, 0x00, 0x00, 0x69,
0x86, 0x86, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x08, 0x90, 0x86, 0x00, 0x00, 0x69, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x90, 0x86, 0x00, 0x66, 0x61, 0x46, 0x00, 0x66, 0x02, 0x62,
0x26, 0x66, 0x6A, 0x06, 0x69, 0x88, 0x96, 0x00, 0x69, 0x38, 0x96, 0x00, 0x69, 0x83, 0x96, 0x00, 0x62, 0x16, 0x86, 0x00,
0x62, 0x06, 0x00, 0x00, 0x69, 0x83, 0x96, 0x00, 0x80, 0x86, 0x09, 0x62, 0x86, 0x86, 0x00, 0x90, 0x66, 0x26, 0x00, 0x80,
0x66, 0x6A, 0x86, 0x00, 0x61, 0x69, 0xA6, 0x00, 0x00, 0x68, 0x03, 0x00, 0x68, 0x93, 0x49, 0x00, 0x68, 0x83, 0x86, 0x00,
0x90, 0x66, 0x00, 0x65, 0x9B, 0x49, 0x00, 0x69, 0x38, 0x16, 0x00, 0x99, 0x69, 0x86, 0x09, 0x66, 0x63, 0x26, 0x00, 0x69,
0x36, 0x86, 0x00, 0x61, 0x06, 0x00, 0x00, 0x69, 0x36, 0x86, 0x00, 0x66, 0x61, 0x96, 0x00, 0x92, 0x09, 0x20, 0x29, 0x00,
0x00, 0x69, 0x08, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x99, 0x00, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x90, 0x86,
0x00, 0x66, 0x5A, 0x16, 0x00, 0x66, 0x02, 0x62, 0x26, 0x66, 0x62, 0x06, 0x69, 0x88, 0x96, 0x00, 0x80, 0x66, 0x08, 0x00,
0x69, 0x55, 0xA5, 0x00, 0x30, 0x56, 0x86, 0x00, 0x6A, 0x06, 0x00, 0x00, 0x30, 0x66, 0x01, 0x00, 0x90, 0x66, 0x08, 0x30,
0x36, 0x36, 0x00, 0x20, 0x66, 0x06, 0x00, 0x80, 0x66, 0x50, 0x16, 0x00, 0x68, 0x8A, 0x16, 0x00, 0x00, 0x69, 0x08, 0x00,
0x68, 0x66, 0x26, 0x00, 0x5A, 0x66, 0xA5, 0x00, 0x90, 0x66, 0x00, 0x66, 0x66, 0x26, 0x00, 0x34, 0x66, 0x25, 0x00, 0x00,
0x60, 0x96, 0x00, 0x69, 0x66, 0x01, 0x00, 0x54, 0x66, 0x25, 0x00, 0x63, 0x08, 0x00, 0x00, 0x34, 0x66, 0x25, 0x00, 0x61,
0x66, 0x43, 0x00, 0x69, 0x08, 0x90, 0x86, 0x00, 0x00, 0x69, 0x08, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x08, 0x00, 0x00, 0x00, 0x90, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x90, 0x68, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xA2, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xA8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x09, 0x00, 0x00,
0x00, 0x90, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0xA0, 0x26, 0x00, 0xA0, 0xA6, 0x9B, 0x00, 0x80, 0x08,
0x00, 0x90, 0x08, 0x00, 0x18, 0x00, 0x80, 0x08, 0x00, 0x95, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x10, 0x98, 0x05, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x02, 0x00, 0xB0, 0x89, 0x01, 0x00, 0x90, 0x56, 0x63, 0x0A, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0x00, 0x00, 0x20,
0x09, 0x00, 0x00, 0x09, 0xA9, 0x00, 0x40, 0x09, 0x00, 0x90, 0x09, 0x00, 0x94, 0x00, 0x90, 0x04, 0x00, 0x92, 0x00, 0x00,
0x00, 0x90, 0x04, 0x00, 0x90, 0xA2, 0x09, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x92, 0x00, 0x00, 0x90, 0x2A, 0x02, 0x00,
0x80, 0x11, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x08, 0x69, 0x96, 0x00, 0x66, 0x0B, 0x00, 0x69, 0x61, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A,
0x08, 0x00, 0x63, 0x36, 0x00, 0x00, 0x00, 0x66, 0x16, 0x00, 0x90, 0x66, 0x96, 0x00, 0x66, 0x66, 0x09, 0x66, 0x66, 0x09,
0x66, 0x09, 0x69, 0x06, 0x8A, 0x66, 0xA8, 0x00, 0x90, 0x6B, 0x9B, 0x00, 0x8A, 0x66, 0xA8, 0x00, 0x90, 0x6B, 0x66, 0x00,
0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x26, 0x61, 0x01, 0x10, 0x66, 0xA8, 0x00, 0x90, 0x05, 0x00, 0x00,
0x6A, 0x02, 0x00, 0x6A, 0xBA, 0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x6A, 0x0A, 0x00, 0x59, 0x00, 0x10, 0x08, 0x00, 0x95,
0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x50, 0x89, 0x08, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x6A, 0xBA,
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x68, 0x48, 0x00, 0x69, 0x26, 0x00, 0x31, 0x69, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x04, 0x00, 0x66, 0x66, 0x00, 0x00, 0x20, 0x66, 0x86, 0x00, 0x90, 0x66,
0x96, 0x00, 0x66, 0x98, 0x02, 0x66, 0x98, 0x02, 0x66, 0x09, 0x61, 0x06, 0x61, 0x35, 0x16, 0x00, 0x6A, 0x86, 0x66, 0x0A,
0x61, 0x35, 0x86, 0x00, 0x6A, 0x86, 0x66, 0x0A, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x16, 0x69, 0x09,
0x69, 0x86, 0x86, 0x00, 0x00, 0x49, 0x00, 0x00, 0x92, 0x00, 0x00, 0x90, 0x10, 0x0A, 0x00, 0x92, 0x00, 0x00, 0x00, 0x92,
0x00, 0x00, 0x90, 0x04, 0x90, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x90, 0x9A, 0x02, 0x00, 0x00, 0x22,
0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x90, 0x90, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x68, 0x09, 0x00,
0x60, 0x26, 0x00, 0x95, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x66, 0x66,
0x04, 0x00, 0x20, 0x66, 0x36, 0x00, 0x10, 0x66, 0x16, 0x00, 0x66, 0x09, 0x00, 0x66, 0x09, 0x00, 0x66, 0x09, 0x69, 0x06,
0x63, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x02, 0x69, 0x96, 0x66, 0x00,
0x66, 0x69, 0x96, 0x00, 0x69, 0x36, 0x69, 0x09, 0x69, 0x96, 0x86, 0x00, 0x10, 0x88, 0x0A, 0x20, 0x88, 0x09, 0x00, 0x10,
0x18, 0x0A, 0x90, 0x88, 0x09, 0x00, 0x90, 0x88, 0x09, 0x00, 0x82, 0x01, 0x89, 0x01, 0x90, 0x83, 0x01, 0x00, 0x10, 0x88,
0x09, 0x00, 0x10, 0x18, 0x09, 0x00, 0x89, 0x89, 0xA8, 0x00, 0x89, 0x89, 0xA8, 0x00, 0x88, 0x89, 0x03, 0x1A, 0x13, 0x0A,
0x00, 0x00, 0x00, 0x11, 0x00, 0x68, 0x09, 0x00, 0x60, 0x26, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x66, 0x66, 0x0A, 0x00, 0x90, 0x66, 0x66, 0x00, 0x30, 0x66, 0x86, 0x00, 0x66, 0x09,
0x00, 0x66, 0x09, 0x00, 0x66, 0x09, 0x61, 0x06, 0x68, 0x88, 0x86, 0x00, 0x6A, 0x96, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00,
0x62, 0x86, 0x66, 0x02, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x61, 0x66, 0x61, 0x09, 0x69, 0x96, 0x86, 0x00,
0x61, 0x68, 0x05, 0x6A, 0x35, 0x96, 0x00, 0x68, 0x68, 0x05, 0x69, 0x35, 0x96, 0x00, 0x69, 0x33, 0x96, 0x00, 0x69, 0x08,
0x69, 0x08, 0x69, 0x53, 0x16, 0x00, 0x68, 0x63, 0xA6, 0x00, 0x68, 0x68, 0xA6, 0x00, 0x68, 0x69, 0x26, 0x00, 0x63, 0x69,
0x26, 0x00, 0x66, 0x69, 0x06, 0x6B, 0x68, 0x05, 0x00, 0x00, 0x00, 0x25, 0x00, 0x68, 0x09, 0x00, 0x60, 0x26, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x90, 0x66, 0x66, 0x09, 0x00, 0x10, 0x66,
0x66, 0x04, 0x30, 0x66, 0xB6, 0x00, 0x66, 0x98, 0x04, 0x66, 0x98, 0x04, 0x66, 0x09, 0x69, 0x06, 0x68, 0x88, 0x86, 0x00,
0x62, 0x96, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00, 0x62, 0xB6, 0x66, 0x02, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00,
0x69, 0x66, 0x63, 0x09, 0x61, 0x06, 0x00, 0x00, 0x68, 0x69, 0x06, 0x62, 0x38, 0x96, 0x00, 0x68, 0x69, 0x06, 0x61, 0x88,
0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x69, 0x08, 0x69, 0x88, 0x96, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69,
0xA6, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0xA6, 0x00, 0x66, 0x69, 0x06, 0x66, 0x69, 0x06, 0x00, 0x00, 0x90, 0x06,
0x00, 0x68, 0x09, 0x00, 0x60, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x88, 0x00, 0x00,
0x00, 0x90, 0x86, 0x68, 0x09, 0x00, 0x80, 0x96, 0x66, 0x02, 0x60, 0x96, 0x66, 0x00, 0x66, 0x83, 0x0A, 0x66, 0x85, 0x0A,
0x66, 0x09, 0x69, 0x06, 0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00, 0x62, 0x66, 0x66, 0x02,
0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x63, 0x66, 0x09, 0x69, 0x06, 0x00, 0x00, 0x89, 0x68, 0x06, 0x8A,
0x38, 0x96, 0x00, 0x81, 0x68, 0x06, 0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x08, 0x69, 0x08, 0x69, 0x88,
0x96, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x63, 0x69, 0x26, 0x00, 0x66, 0x69,
0x06, 0x66, 0x69, 0x06, 0x00, 0x00, 0x10, 0x08, 0x00, 0x68, 0x09, 0x00, 0x60, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x68, 0x26,
0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB6, 0x63, 0x01, 0x00, 0x50, 0x86, 0x66, 0x09, 0x6A, 0x86,
0x66, 0x0A, 0x66, 0x09, 0x00, 0x66, 0x09, 0x00, 0x66, 0x09, 0x61, 0x06, 0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x02,
0x68, 0x88, 0x86, 0x00, 0x62, 0xB6, 0x66, 0x02, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x61, 0x66, 0x09,
0x69, 0x46, 0xAA, 0x00, 0x8A, 0x66, 0x06, 0x90, 0x65, 0x96, 0x00, 0x8A, 0x66, 0x06, 0x69, 0x66, 0x96, 0x00, 0x69, 0x66,
0x96, 0x00, 0x69, 0x08, 0x69, 0x08, 0x69, 0x88, 0x16, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69,
0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x66, 0x69, 0x06, 0x66, 0x29, 0x02, 0x00, 0x00, 0x30, 0x02, 0x00, 0x68, 0x09, 0x00,
0x60, 0x26, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x02, 0x00, 0x24, 0x31, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x36, 0x65,
0x08, 0x00, 0x60, 0x36, 0x65, 0x09, 0x62, 0x86, 0x66, 0x02, 0x66, 0x09, 0x00, 0x66, 0x09, 0x00, 0x66, 0x09, 0x69, 0x06,
0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00, 0x62, 0x16, 0x66, 0x02, 0x69, 0x96, 0x66, 0x00,
0x66, 0x69, 0x96, 0x00, 0x61, 0xB9, 0x66, 0x09, 0x69, 0x96, 0x86, 0x00, 0x63, 0x68, 0x06, 0x69, 0x83, 0x96, 0x00, 0x63,
0x68, 0x06, 0x69, 0x88, 0x98, 0x00, 0x61, 0x13, 0x98, 0x00, 0x69, 0x08, 0x69, 0x08, 0x69, 0x88, 0x96, 0x00, 0x68, 0x69,
0x26, 0x00, 0x68, 0x61, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x66, 0x69, 0x06, 0x66, 0x69, 0x06,
0x00, 0x00, 0x6A, 0x00, 0x00, 0x68, 0x09, 0x00, 0x60, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x66, 0x86,
0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x96, 0x69, 0x0B, 0x00, 0x6A, 0x26, 0x68, 0x08, 0x69, 0x06, 0x66, 0x09, 0x66, 0x09,
0x00, 0x66, 0x09, 0x00, 0x66, 0x01, 0x69, 0x06, 0x68, 0x88, 0x86, 0x00, 0x62, 0x96, 0x66, 0x02, 0x68, 0x88, 0x86, 0x00,
0x62, 0x16, 0x66, 0x02, 0x69, 0x96, 0x66, 0x00, 0x66, 0x69, 0x96, 0x00, 0x69, 0x19, 0x66, 0x09, 0x69, 0x16, 0x86, 0x00,
0x66, 0x69, 0x06, 0x69, 0x88, 0x96, 0x00, 0x66, 0x69, 0x06, 0x69, 0x88, 0x96, 0x00, 0x69, 0x88, 0x96, 0x00, 0x69, 0x03,
0x69, 0x08, 0x69, 0x83, 0x96, 0x00, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0xA6, 0x00, 0x63, 0x69, 0xA6, 0x00, 0x68, 0x69,
0x26, 0x00, 0x66, 0x69, 0x06, 0x66, 0x69, 0x06, 0x99, 0x00, 0x81, 0x00, 0x00, 0x68, 0x48, 0x00, 0x62, 0x26, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x60, 0x96, 0x69, 0x06, 0x00, 0x62, 0x26,
0x68, 0x08, 0x69, 0x06, 0x66, 0x09, 0x66, 0x98, 0x02, 0x66, 0x18, 0x0A, 0x66, 0x09, 0x69, 0x06, 0x68, 0x33, 0x86, 0x00,
0x62, 0x86, 0x66, 0x02, 0x68, 0x38, 0x86, 0x00, 0x6A, 0x16, 0x66, 0x02, 0x69, 0x16, 0x66, 0x00, 0x66, 0x61, 0x96, 0x00,
0x69, 0x99, 0x66, 0x09, 0x69, 0x16, 0x86, 0x00, 0x66, 0x61, 0x06, 0x69, 0x88, 0x96, 0x00, 0x66, 0x61, 0x06, 0x69, 0x83,
0x96, 0x00, 0x69, 0x33, 0x96, 0x00, 0x61, 0x08, 0x69, 0x08, 0x69, 0x33, 0x16, 0x00, 0x68, 0x61, 0x26, 0x00, 0x68, 0x61,
0x26, 0x00, 0x68, 0x61, 0x26, 0x00, 0x68, 0x61, 0x26, 0x00, 0x66, 0x61, 0x06, 0x66, 0x61, 0x06, 0x66, 0x00, 0x13, 0x00,
0x00, 0x52, 0x96, 0x00, 0x66, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x66, 0x00, 0x00,
0x00, 0x62, 0x96, 0x69, 0x26, 0x00, 0x69, 0x06, 0x61, 0x06, 0x68, 0x03, 0x63, 0x08, 0x66, 0x66, 0x09, 0x66, 0x66, 0x01,
0x66, 0x01, 0x69, 0x06, 0x52, 0x66, 0xA5, 0x00, 0x80, 0x66, 0x16, 0x00, 0x59, 0x66, 0xA5, 0x00, 0x60, 0x66, 0x86, 0x00,
0x34, 0x66, 0x96, 0x00, 0x69, 0x66, 0x08, 0x00, 0x69, 0x09, 0x66, 0x09, 0x34, 0x66, 0x95, 0x00, 0x61, 0x65, 0x06, 0x5A,
0x56, 0x96, 0x00, 0x61, 0x65, 0x06, 0x80, 0x66, 0x08, 0x00, 0x80, 0x66, 0x08, 0x00, 0x69, 0x08, 0x69, 0x08, 0x10, 0x66,
0x08, 0x00, 0x3A, 0x66, 0x01, 0x00, 0x3A, 0x66, 0x01, 0x00, 0x69, 0x63, 0xA6, 0x00, 0x69, 0x65, 0x26, 0x00, 0x61, 0x63,
0x06, 0x39, 0x56, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2A, 0x04, 0x00,
0x00, 0x2A, 0x00, 0x00, 0x8A, 0x24, 0x04, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1B, 0x44, 0x00, 0xA0, 0x0A, 0x42,
0x00, 0x00, 0x24, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x63, 0x02, 0x20, 0xB6, 0x08, 0x00, 0x10, 0x55, 0x09, 0x00, 0x60, 0x66, 0x86, 0x00, 0x00, 0x68, 0x09, 0x00, 0x68,
0x09, 0x59, 0xB8, 0x29, 0x00, 0x61, 0x66, 0x26, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x00, 0x69, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9A, 0x94, 0x09, 0x90, 0x49, 0xA9, 0x00, 0x90, 0x22, 0x09, 0x00, 0x60,
0x16, 0x65, 0x09, 0x00, 0x99, 0x02, 0x00, 0x99, 0x02, 0x22, 0x44, 0x64, 0x00, 0x99, 0x9A, 0x09, 0x00, 0x20, 0x09, 0x29,
0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x13, 0x0A, 0x90,
0x88, 0x09, 0x00, 0x81, 0x82, 0xA8, 0x00, 0x60, 0x26, 0x68, 0x09, 0x00, 0x68, 0x09, 0x00, 0x68, 0x09, 0x81, 0x81, 0x09,
0x00, 0x89, 0x81, 0x09, 0x00, 0x20, 0x81, 0x01, 0x00, 0x00, 0x00, 0x95, 0x00, 0x90, 0x81, 0x11, 0x18, 0x0A, 0x1A, 0x88,
0x81, 0xA1, 0x00, 0x10, 0x66, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x68, 0x68, 0x05, 0x69, 0x53, 0x96, 0x00, 0x68, 0x61, 0xA6, 0x00, 0x60, 0x26, 0x68, 0x09, 0x00,
0x63, 0x09, 0x00, 0x68, 0x09, 0x68, 0x63, 0x26, 0x00, 0x63, 0x6B, 0x26, 0x00, 0x6A, 0x86, 0x86, 0x00, 0x00, 0x00, 0x01,
0x00, 0x6A, 0x86, 0x66, 0x68, 0x08, 0x61, 0x61, 0x86, 0x16, 0x00, 0x60, 0xAA, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x69, 0x06, 0x69, 0x88, 0x96, 0x00, 0x68,
0x69, 0x26, 0x00, 0x60, 0x96, 0x55, 0x0A, 0xA0, 0x66, 0x04, 0x00, 0x68, 0x09, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0xA6,
0x00, 0x6A, 0x96, 0x86, 0x00, 0x8A, 0x01, 0x00, 0x00, 0x6A, 0x96, 0x66, 0x69, 0x08, 0x68, 0x62, 0x96, 0x36, 0x00, 0x60,
0x1A, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x81, 0x68, 0x06, 0x69, 0x88, 0x96, 0x00, 0x68, 0x69, 0x26, 0x00, 0x60, 0x96, 0x86, 0x00, 0x30, 0x16, 0x00, 0x00, 0x68,
0x09, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x62, 0x16, 0x86, 0x00, 0x8A, 0x01, 0x00, 0x00, 0x62, 0x96, 0x66,
0x69, 0x08, 0x81, 0x61, 0x96, 0x86, 0x00, 0x6A, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x66, 0x06, 0x69, 0x66, 0x96, 0x00, 0x68, 0x69, 0xA6, 0x00, 0x60,
0x26, 0x68, 0x01, 0x62, 0x25, 0x98, 0x00, 0x68, 0x09, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x62, 0x96, 0x86,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x96, 0x66, 0x66, 0x08, 0x3A, 0x66, 0x66, 0x86, 0x00, 0x61, 0x16, 0xA1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x68, 0x06, 0x69,
0x13, 0x28, 0x00, 0x68, 0x69, 0x26, 0x00, 0x60, 0x26, 0x68, 0x09, 0x69, 0x98, 0x96, 0x00, 0x68, 0x09, 0x68, 0x69, 0x26,
0x00, 0x68, 0x69, 0x26, 0x00, 0x62, 0x96, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x96, 0x66, 0x99, 0x09, 0x6B, 0x69,
0x96, 0x99, 0x00, 0x16, 0x6A, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x69, 0x06, 0x69, 0x88, 0x96, 0x00, 0x68, 0x69, 0x26, 0x00, 0x60, 0x26, 0x68, 0x09, 0x69,
0x98, 0x16, 0x00, 0x63, 0x09, 0x68, 0x69, 0xA6, 0x00, 0x68, 0x61, 0x26, 0x00, 0x62, 0x96, 0x86, 0x00, 0x00, 0x00, 0x00,
0x00, 0x6A, 0x96, 0x66, 0x69, 0x08, 0x66, 0x6A, 0x96, 0x86, 0x00, 0xA6, 0xA0, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x61, 0x06, 0x69, 0x33, 0x96, 0x00, 0x68,
0x61, 0xA6, 0x00, 0x69, 0x26, 0x63, 0x09, 0x69, 0x83, 0x96, 0x00, 0x68, 0x09, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26,
0x00, 0x62, 0x16, 0x86, 0x00, 0x94, 0x09, 0x00, 0x00, 0x62, 0x16, 0x66, 0x68, 0x01, 0x66, 0x69, 0x16, 0x86, 0x00, 0x16,
0x1A, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x65, 0x06, 0x80, 0x66, 0x08, 0x00, 0x69, 0x63, 0x26, 0x00, 0x68, 0x28, 0x16, 0x00, 0x10, 0x66, 0x08, 0x00, 0x68,
0x09, 0x68, 0x69, 0x26, 0x00, 0x68, 0x69, 0x26, 0x00, 0x10, 0x65, 0xA3, 0x00, 0x62, 0x08, 0x00, 0x00, 0x90, 0x65, 0x53,
0x36, 0x0A, 0x61, 0x86, 0x63, 0xA3, 0x00, 0x61, 0x66, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
struct UVWH
{
uchar u, v;
uchar w, h;
};
UVWH fmvFontUV[256] =
{
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 222, 18, 3, 18 }, { 22, 36, 5, 18 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 94, 54, 6, 18 }, { 70, 54, 3, 18 },
{ 10, 36, 4, 18 }, { 16, 36, 4, 18 }, { 0, 0, 0, 0 }, { 34, 36, 6, 18 },
{ 246, 18, 2, 18 }, { 28, 36, 4, 18 }, { 0, 36, 2, 18 }, { 4, 36, 5, 18 },
{ 144, 18, 6, 18 }, { 152, 18, 4, 18 }, { 158, 18, 6, 18 }, { 166, 18, 6, 18 },
{ 174, 18, 7, 18 }, { 182, 18, 6, 18 }, { 190, 18, 6, 18 }, { 198, 18, 6, 18 },
{ 206, 18, 6, 18 }, { 214, 18, 6, 18 }, { 42, 36, 2, 18 }, { 66, 54, 3, 18 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 226, 18, 6, 18 },
{ 0, 0, 0, 0 }, { 0, 0, 7, 18 }, { 8, 0, 6, 18 }, { 16, 0, 6, 18 },
{ 24, 0, 6, 18 }, { 32, 0, 6, 18 }, { 40, 0, 5, 18 }, { 46, 0, 6, 18 },
{ 54, 0, 6, 18 }, { 62, 0, 3, 18 }, { 66, 0, 6, 18 }, { 74, 0, 6, 18 },
{ 82, 0, 5, 18 }, { 88, 0, 9, 18 }, { 98, 0, 6, 18 }, { 106, 0, 6, 18 },
{ 114, 0, 6, 18 }, { 122, 0, 6, 18 }, { 130, 0, 7, 18 }, { 138, 0, 7, 18 },
{ 146, 0, 6, 18 }, { 154, 0, 6, 18 }, { 162, 0, 7, 18 }, { 170, 0, 10, 18 },
{ 182, 0, 7, 18 }, { 190, 0, 7, 18 }, { 198, 0, 6, 18 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 206, 0, 6, 18 }, { 214, 0, 6, 18 }, { 222, 0, 5, 18 },
{ 228, 0, 5, 18 }, { 234, 0, 6, 18 }, { 242, 0, 5, 18 }, { 248, 0, 6, 18 },
{ 0, 18, 6, 18 }, { 8, 18, 3, 18 }, { 12, 18, 4, 18 }, { 18, 18, 6, 18 },
{ 26, 18, 3, 18 }, { 30, 18, 9, 18 }, { 40, 18, 6, 18 }, { 48, 18, 6, 18 },
{ 56, 18, 6, 18 }, { 64, 18, 6, 18 }, { 72, 18, 6, 18 }, { 80, 18, 6, 18 },
{ 88, 18, 5, 18 }, { 94, 18, 6, 18 }, { 102, 18, 7, 18 }, { 110, 18, 9, 18 },
{ 120, 18, 6, 18 }, { 128, 18, 7, 18 }, { 136, 18, 6, 18 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 238, 18, 6, 18 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 38, 54, 3, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 30, 54, 6, 18 },
{ 50, 36, 8, 18 }, { 60, 36, 7, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 68, 36, 7, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 152, 36, 6, 18 },
{ 76, 36, 5, 18 }, { 82, 36, 5, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 88, 36, 3, 18 }, { 92, 36, 3, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 144, 36, 7, 18 }, { 96, 36, 6, 18 }, { 104, 36, 7, 18 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 112, 36, 6, 18 }, { 0, 0, 0, 0 },
{ 120, 36, 7, 18 }, { 0, 0, 0, 0 }, { 128, 36, 6, 18 }, { 0, 0, 0, 0 },
{ 136, 36, 6, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 22, 54, 7, 18 },
{ 160, 36, 5, 18 }, { 166, 36, 6, 18 }, { 0, 54, 5, 18 }, { 0, 0, 0, 0 },
{ 174, 36, 5, 18 }, { 0, 0, 0, 0 }, { 84, 54, 8, 18 }, { 250, 36, 5, 18 },
{ 180, 36, 6, 18 }, { 188, 36, 6, 18 }, { 6, 54, 6, 18 }, { 0, 0, 0, 0 },
{ 196, 36, 3, 18 }, { 200, 36, 3, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 50, 54, 6, 18 }, { 204, 36, 6, 18 }, { 212, 36, 6, 18 },
{ 58, 54, 6, 18 }, { 0, 0, 0, 0 }, { 220, 36, 6, 18 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 228, 36, 6, 18 }, { 236, 36, 6, 18 }, { 14, 54, 6, 18 },
{ 244, 36, 5, 18 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
};

View File

@ -25,6 +25,7 @@
#include "SKY.H"
#include "DEBRIS.H"
#include <stdint.h>
#include <math.h>
#include "FELONY.H"
@ -633,7 +634,7 @@ void LoadLevelSFX(int missionNum)
LoadSoundBankDynamic(NULL, 1, 0);
LoadSoundBankDynamic(NULL, 3, 3);
if (gCurrentMissionNumber - 39U < 2)
if (missionNum - 39U < 2 || missionNum >= 400 && missionNum <= 404)
LoadBankFromLump(SOUND_BANK_CARS, MapCarIndexToBank(4));
else
LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(0));
@ -645,17 +646,17 @@ void LoadLevelSFX(int missionNum)
LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(1));
}
if (missionNum - 50U < 16)
if (missionNum - 50U < 16 || missionNum >= 400)
{
LoadBankFromLump(SOUND_BANK_CARS, SpecialVehicleKludge(2));
}
// disable cop speech on specific missions (gangs)
// and set cop model (car sound bank)
if (gCurrentMissionNumber == 7 || gCurrentMissionNumber == 9 ||
gCurrentMissionNumber == 11 || gCurrentMissionNumber == 20 ||
gCurrentMissionNumber == 26 || gCurrentMissionNumber == 31 ||
gCurrentMissionNumber == 33 || gCurrentMissionNumber == 40)
if (missionNum == 7 || missionNum == 9 ||
missionNum == 11 || missionNum == 20 ||
missionNum == 26 || missionNum == 31 ||
missionNum == 33 || missionNum == 40)
{
gDoCopSpeech = 0;
@ -3630,7 +3631,18 @@ unsigned int horn_time;
// [D] [T]
void InitLeadHorn(void)
{
horn_time = 0;
// [A] disable horns in some missions
switch (gCurrentMissionNumber)
{
case 4: // Tailing the drop
case 10: // Follow up the lead
case 18: // Tail Jericho
case 26: // Steal the ambulance
horn_time = 0xFFFFFFFF;
break;
default:
horn_time = 0;
}
}
@ -3665,6 +3677,10 @@ void LeadHorn(CAR_DATA* cp)
int carBank;
int dx,dz;
// [A] disabled horn in those missions
if (horn_time == 0xFFFFFFFF)
return;
// [A] do not horn if too far from camera
dx = cp->hd.where.t[0] - camera_position.vx >> 8;
dz = cp->hd.where.t[2] - camera_position.vz >> 8;

View File

@ -758,7 +758,7 @@ void LaunchGame(void)
fakeOtherPlayer = 0;
ResetGraph(1);
SetVideoMode(1);
SetVideoMode(video_mode);
gMissionCompletionState = PAUSEMODE_GAMEOVER;

View File

@ -8,9 +8,11 @@
#include "DRAW.H"
#include "DEBRIS.H"
#include "SYSTEM.H"
#include "../ASM/ASMTEST.H"
#include "INLINE_C.H"
#include "RAND.H"
EXOBJECT explosion[MAX_EXPLOSION_OBJECTS];
@ -51,7 +53,7 @@ MATRIX SS = { 0 };
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void InitExObjects(void)
{
int i;
@ -87,7 +89,7 @@ void InitExObjects(void)
/* end block 3 */
// End Line: 264
// [D]
// [D] [T]
void AddExplosion(VECTOR pos, int type)
{
EXOBJECT *newExplosion;
@ -96,13 +98,10 @@ void AddExplosion(VECTOR pos, int type)
i = 0;
newExplosion = explosion;
while (newExplosion->time != -1)
while (newExplosion->time != -1 && i < MAX_EXPLOSION_OBJECTS)
{
i++;
newExplosion++;
if (i > 4)
return;
i++;
}
newExplosion->time = 0;
@ -111,21 +110,21 @@ void AddExplosion(VECTOR pos, int type)
if (type == LITTLE_BANG)
{
newExplosion->speed = 0xc0;
newExplosion->hscale = 0x400;
newExplosion->rscale = 0x400;
newExplosion->speed = 192;
newExplosion->hscale = 1024;
newExplosion->rscale = 1024;
}
else if (type == BIG_BANG)
{
newExplosion->speed = 0x80;
newExplosion->hscale = 0x1000;
newExplosion->rscale = 0x1000;
newExplosion->speed = 128;
newExplosion->hscale = 4096;
newExplosion->rscale = 4096;
}
else if (type == HEY_MOMMA)
{
newExplosion->speed = 0x40;
newExplosion->hscale = 0x4000;
newExplosion->rscale = 0x4000;
newExplosion->speed = 64;
newExplosion->hscale = 16384;
newExplosion->rscale = 16384;
}
}
@ -175,13 +174,17 @@ void AddExplosion(VECTOR pos, int type)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void HandleExplosion(void)
{
VECTOR drift;
VECTOR smokePos;
CAR_DATA *cp;
EXOBJECT *exp;
int i;
GetSmokeDrift(&drift); // [A]
if (pauseflag != 0)
return;
@ -204,7 +207,7 @@ void HandleExplosion(void)
i++;
exp++;
};
}
i = 0;
@ -214,7 +217,17 @@ void HandleExplosion(void)
if (exp->time != -1)
{
if (exp->time == 0)
{
ExplosionSound(&exp->pos, exp->type);
}
// [A] add smoke to explosions
if(exp->time > 1500 && (CameraCnt & 0x3) == 0)
{
smokePos = exp->pos;
smokePos.vy -= 120;
Setup_Smoke(&smokePos, 100 + (rand() & 15) * 20, 900, SMOKE_BLACK, 0, &drift, 0);
}
exp->time += exp->speed;
@ -224,7 +237,7 @@ void HandleExplosion(void)
exp++;
i++;
};
}
}
@ -274,7 +287,7 @@ void HandleExplosion(void)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void DrawAllExplosions(void)
{
int i;
@ -285,7 +298,7 @@ void DrawAllExplosions(void)
DrawExplosion(explosion[i].time, explosion[i].pos, explosion[i].hscale, explosion[i].rscale);
i++;
};
}
}
@ -327,85 +340,86 @@ void DrawAllExplosions(void)
SVECTOR globemesh[54];
// [D]
// [D] [T]
void initExplosion(void)
{
short sVar1;
short sVar2;
uint uVar3;
SVECTOR *pSVar4;
uint uVar5;
int iVar6;
uint uVar7;
int puVar8;
uint uVar9;
SVECTOR *vert;
int i;
int d1, d2;
uVar7 = 128;
pSVar4 = globemesh;
uVar9 = 0;
// generate half-globe mesh
vert = globemesh;
d1 = 0;
d2 = 128;
i = 0;
do {
uVar3 = uVar7 & 0xfff;
uVar7 = uVar7 + 0x200;
uVar5 = uVar9 + 2;
vert[0].vy = 5;
vert[1].vy = -265;
pSVar4->vy = 5;
pSVar4[1].vy = -0x109;
vert[0].vx = FIXEDH(rcossin_tbl[(d1 & 0xf) * 512 + 1] * 512);
vert[0].vz = FIXEDH(rcossin_tbl[(d1 & 0xf) * 512] * 512);
pSVar4->vx = FIXEDH(rcossin_tbl[(uVar9 & 0xf) * 0x200 + 1] * 0x200);
pSVar4->vz = FIXEDH(rcossin_tbl[(uVar9 & 0xf) * 0x200] * 0x200);
vert[1].vx = FIXEDH(rcossin_tbl[(d2 & 0xfff) * 2 + 1] * 490);
vert[1].vz = FIXEDH(rcossin_tbl[(d2 & 0xfff) * 2] * 490);
pSVar4[1].vx = FIXEDH(rcossin_tbl[uVar3 * 2 + 1] * 0x1ea);
pSVar4[1].vz = FIXEDH(rcossin_tbl[uVar3 * 2] * 0x1ea);
vert += 2;
d1 += 2;
d2 += 512;
i++;
} while (i < 18);
pSVar4 = pSVar4 + 2;
uVar9 = uVar5;
} while (uVar5 < 0x12);
vert = globemesh + 18;
d1 = 0x1280;
d2 = 0x1300;
uVar9 = 0x1300;
pSVar4 = globemesh + 18;
puVar8 = 0x1280;
iVar6 = 0x10;
i = 0;
do {
uVar3 = uVar9 & 0xfff;
uVar9 = uVar9 + 0x200;
uVar7 = (uint)puVar8 & 0xfff;
puVar8 = puVar8 + 0x200;
iVar6 = iVar6 + -2;
vert[0].vy = -265;
vert[1].vy = -505;
pSVar4->vy = -0x109;
pSVar4[1].vy = -0x1f9;
vert[0].vx = FIXEDH(rcossin_tbl[(d1 & 0xfff) * 2 + 1] * 490);
vert[0].vz = FIXEDH(rcossin_tbl[(d1 & 0xfff) * 2] * 490);
pSVar4->vx = FIXEDH(rcossin_tbl[uVar7 * 2 + 1] * 0x1ea);
pSVar4->vz = FIXEDH(rcossin_tbl[uVar7 * 2] * 0x1ea);
vert[1].vx = FIXEDH(rcossin_tbl[(d2 & 0xfff) * 2 + 1] * 330);
vert[1].vz = FIXEDH(rcossin_tbl[(d2 & 0xfff) * 2] * 330);
pSVar4[1].vx = FIXEDH(rcossin_tbl[uVar3 * 2 + 1] * 0x14a);
pSVar4[1].vz = FIXEDH(rcossin_tbl[uVar3 * 2] * 0x14a);
vert += 2;
pSVar4 = pSVar4 + 2;
} while (-1 < iVar6);
d1 += 512;
d2 += 512;
i += 2;
} while (i < 18);
puVar8 = 9600;
pSVar4 = globemesh + 36;
uVar9 = 0x2500;
iVar6 = 0x10;
vert = globemesh + 36;
d1 = 0x2500;
d2 = 9600;
i = 0;
do {
uVar3 = (uint)puVar8 & 0xfff;
puVar8 = puVar8 + 0x200;
uVar7 = uVar9 & 0xfff;
uVar9 = uVar9 + 0x200;
iVar6 = iVar6 + -2;
vert[0].vy = -505;
vert[1].vy = -617;
pSVar4->vy = -0x1f9;
pSVar4[1].vy = -0x269;
vert[0].vx = FIXEDH(rcossin_tbl[(d1 & 0xfff) * 2 + 1] * 330);
vert[0].vz = FIXEDH(rcossin_tbl[(d1 & 0xfff) * 2] * 330);
pSVar4->vx = FIXEDH(rcossin_tbl[uVar7 * 2 + 1] * 0x14a);
pSVar4->vz = FIXEDH(rcossin_tbl[uVar7 * 2] * 0x14a);
vert[1].vx = FIXEDH(rcossin_tbl[(d2 & 0xfff) * 2 + 1] * 100);
vert[1].vz = FIXEDH(rcossin_tbl[(d2 & 0xfff) * 2] * 100);
pSVar4[1].vx = FIXEDH(rcossin_tbl[uVar3 * 2 + 1] * 100);
pSVar4[1].vz = FIXEDH(rcossin_tbl[uVar3 * 2] * 100);
vert += 2;
d1 += 512;
d2 += 512;
pSVar4 = pSVar4 + 2;
} while (-1 < iVar6);
i += 2;
} while (i < 18);
}
@ -492,51 +506,52 @@ void initExplosion(void)
/* end block 3 */
// End Line: 1279
// [D]
// [D] [T]
void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
{
int iVar3;
int i;
int j;
POLY_FT4 *poly;
SVECTOR *src;
int uVar6;
uint uVar7;
uint uVar8;
int iVar9;
int iVar10;
int iVar11;
int iVar12;
int iVar13;
int rgb, transparency;
int red, green, blue;
int sf, sf1, sf2;
uint u0, u1,u2,u3;
int i;
VECTOR v;
MATRIX workmatrix;
int z;
uVar8 = *(ushort*)&smoke_texture.coords.u0 + 0x200 | *(ushort*)&smoke_texture.clutid << 0x10;
uVar7 = *(ushort*)&smoke_texture.coords.u1 + 0x200 | (*(ushort*)&smoke_texture.tpageid | 0x20) << 0x10;
iVar11 = *(ushort*)&smoke_texture.coords.u2 - 0x800;
iVar10 = *(ushort*)&smoke_texture.coords.u3 - 0x800;
u0 = *(ushort*)&smoke_texture.coords.u0 + 0x200 | *(ushort*)&smoke_texture.clutid << 0x10;
u1 = *(ushort*)&smoke_texture.coords.u1 + 0x200 | (*(ushort*)&smoke_texture.tpageid | 0x20) << 0x10;
u2 = *(ushort*)&smoke_texture.coords.u2 - 0x800;
u3 = *(ushort*)&smoke_texture.coords.u3 - 0x800;
v.vx = position.vx - camera_position.vx;
v.vy = position.vy - camera_position.vy;
v.vz = position.vz - camera_position.vz;
uVar6 = 255 - (time >> 4);
uVar6 = (((uVar6 * uVar6) >> 10) << 8 | ((255 - uVar6) * (uVar6 >> 2) + uVar6 * (uVar6 >> 1)) >> 8) << 8 | uVar6 | 0x2e000000;
transparency = 255 - (time >> 4);
rgb = (transparency * transparency >> 10 << 8 |
(255 - transparency) * (transparency >> 2) + transparency * (transparency >> 1) >> 8) << 8 |
transparency |
0x2e000000;
Apply_Inv_CameraMatrix(&v);
gte_SetTransVector(&v);
iVar12 = 0;
iVar9 = 1;
// [A] modify scale factor to make explosions prettier
sf1 = FIXEDH(time * (5000 - time) * 4) + 12;
sf2 = FIXEDH(time * (10000 - time) * 2) + 12;
i = 0;
do {
iVar3 = (time * (0x37a0 - time) + 0x800 >> 0xc) + 0xc;
i = CameraCnt * (0x40 - iVar12) & 0xfff;
SS.m[1][1] = (short)(iVar3 * hscale >> 0xc);
SS.m[0][0] = (short)((iVar3 * rscale >> 0xc) * (int)rcossin_tbl[i * 2 + 1] + 0x800 >> 0xc);
SS.m[2][0] = (short)((iVar3 * rscale >> 0xc) * (int)rcossin_tbl[i * 2] + 0x800 >> 0xc);
sf = CameraCnt * (64 - i*90) & 0xfff;
SS.m[1][1] = FIXED(sf1 * hscale);
SS.m[0][0] = FIXEDH(FIXED(sf1 * rscale) * rcossin_tbl[sf * 2 + 1]);
SS.m[2][0] = FIXEDH(FIXED(sf1 * rscale) * rcossin_tbl[sf * 2]);
SS.m[0][2] = -SS.m[2][0];
SS.m[2][2] = SS.m[0][0];
@ -545,7 +560,7 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
gte_SetRotMatrix(&workmatrix);
src = globemesh;
i = 0;
j = 0;
do {
poly = (POLY_FT4 *)current->primptr;
@ -553,8 +568,14 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
gte_ldv3(&src[0], &src[1], &src[2]);
gte_rtpt();
*(uint *)&poly[0].r0 = uVar6;
*(uint *)&poly[1].r0 = uVar6;
*(uint *)&poly[0].r0 = rgb;
*(uint *)&poly[1].r0 = rgb;
setPolyFT4(&poly[0]);
setSemiTrans(&poly[0], 1);
setPolyFT4(&poly[1]);
setSemiTrans(&poly[1], 1);
gte_stsxy3(&poly[0].x0, &poly[0].x1, &poly[0].x2);
@ -562,21 +583,20 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
gte_stsz(&z);
iVar3 = 32; // 4 verts step?
if (z > 32)
{
gte_ldv3(&src[3], &src[4], &src[5]);
gte_rtpt();
*(uint *)&poly[0].u0 = uVar8;
*(uint *)&poly[0].u1 = uVar7;
*(uint *)&poly[0].u2 = iVar11;
*(uint *)&poly[0].u3 = iVar10;
*(uint *)&poly[1].u0 = uVar8;
*(uint *)&poly[1].u1 = uVar7;
*(uint *)&poly[1].u2 = iVar11;
*(uint *)&poly[1].u3 = iVar10;
*(uint *)&poly[0].u0 = u0;
*(uint *)&poly[0].u1 = u1;
*(uint *)&poly[0].u2 = u2;
*(uint *)&poly[0].u3 = u3;
*(uint *)&poly[1].u0 = u0;
*(uint *)&poly[1].u1 = u1;
*(uint *)&poly[1].u2 = u2;
*(uint *)&poly[1].u3 = u3;
setPolyFT4(poly);
setSemiTrans(poly, 1);
@ -594,29 +614,30 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
current->primptr += sizeof(POLY_FT4) * 2;
}
if ((i & 3) == 3)
iVar3 = 48; // 6 verts step?
if ((j & 3) == 3)
src += 6;
else
src += 4;
src = (SVECTOR *)((int)&src->vx + iVar3);
j++;
} while (j < 12);
i++;
} while (i < 12);
i++;
} while (i < 2);
iVar9--;
iVar12 += 90;
} while (-1 < iVar9);
transparency = 255 - (time >> 4);
iVar9 = 255 - (time >> 4);
uVar6 = iVar9 >> 1;
iVar12 = 0;
uVar6 = (((uVar6 + (iVar9 * iVar9 >> 10)) >> 1) << 8 | (uVar6 + (((255 - iVar9) * (iVar9 >> 2) + iVar9 * uVar6) >> 8)) >> 1) << 8 | uVar6 | 0x2e000000;
rgb = transparency >> 1;
rgb = (rgb + (transparency * transparency >> 10) >> 1 << 8 |
rgb + ((255 - transparency) * (transparency >> 2) + transparency * rgb >> 8) >> 1) << 8 |
rgb | 0x2e000000;
i = 0;
do {
iVar3 = (time * (0x3930 - time) + 0x800 >> 0xc) + 0xc;
i = CameraCnt * (iVar12 * -0x5a + 0x40) & 0xfff;
SS.m[1][1] = (short)(iVar3 * hscale >> 0xc);
SS.m[0][0] = (short)((iVar3 * rscale >> 0xc) * (int)rcossin_tbl[i * 2 + 1] + 0x800 >> 0xc);
SS.m[2][0] = (short)((iVar3 * rscale >> 0xc) * (int)rcossin_tbl[i * 2] + 0x800 >> 0xc);
sf = CameraCnt * (i * -90 + 64) & 0xfff;
SS.m[1][1] = FIXED(sf2 * hscale);
SS.m[0][0] = FIXEDH(FIXED(sf2 * rscale) * rcossin_tbl[sf * 2 + 1]);
SS.m[2][0] = FIXEDH(FIXED(sf2 * rscale) * rcossin_tbl[sf * 2]);
SS.m[0][2] = -SS.m[2][0];
SS.m[2][2] = SS.m[0][0];
@ -624,9 +645,7 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
gte_SetRotMatrix(&workmatrix);
src = globemesh;
i = 0;
iVar12 = iVar12 + 1;
j = 0;
do {
poly = (POLY_FT4 *)current->primptr;
@ -634,8 +653,8 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
gte_rtpt();
*(uint *)&poly[1].r0 = uVar6;
*(uint *)&poly->r0 = uVar6;
*(uint *)&poly[1].r0 = rgb;
*(uint *)&poly[0].r0 = rgb;
gte_stsxy3(&poly[0].x0, &poly[0].x1, &poly[0].x2);
@ -648,14 +667,14 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
gte_ldv3(&src[3], &src[4], &src[5]);
gte_rtpt();
*(uint *)&poly->u0 = uVar8;
*(uint *)&poly->u1 = uVar7;
*(uint *)&poly->u2 = iVar11;
*(uint *)&poly->u3 = iVar10;
*(uint *)&poly[1].u0 = uVar8;
*(uint *)&poly[1].u1 = uVar7;
*(uint *)&poly[1].u2 = iVar11;
*(uint *)&poly[1].u3 = iVar10;
*(uint *)&poly[0].u0 = u0;
*(uint *)&poly[0].u1 = u1;
*(uint *)&poly[0].u2 = u2;
*(uint *)&poly[0].u3 = u3;
*(uint *)&poly[1].u0 = u0;
*(uint *)&poly[1].u1 = u1;
*(uint *)&poly[1].u2 = u2;
*(uint *)&poly[1].u3 = u3;
setPolyFT4(poly);
setSemiTrans(poly, 1);
@ -673,16 +692,16 @@ void DrawExplosion(int time, VECTOR position, int hscale, int rscale)
current->primptr += sizeof(POLY_FT4) * 2;
}
iVar9 = 0x20;
if (j & 3 == 3)
src += 6;
else
src += 4;
j++;
} while (j < 8);
if (i & 3 == 3)
iVar9 = 0x30;
src = (SVECTOR *)((int)&src->vx + iVar9);
i++;
} while (i < 8);
} while (iVar12 < 2);
i++;
} while (i < 2);
}

View File

@ -8,18 +8,16 @@
#include "SOUND.H"
#include "PAD.H"
#include "MISSION.H"
#include "COP_AI.H"
#include "SCORES.H"
#include "LIBGPU.H"
#include "LIBETC.H"
#include "E3STUFF.H"
#include "PRES.H"
#include "PAUSE.H"
#include "PLATFORM.H"
#ifndef PSX
#include <stdlib.h>
#include <PLATFORM.H>
#include <stdlib.h> // getenv
// [A]
void ShowSavingWaitMessage(char *message, int height)

View File

@ -274,7 +274,7 @@ void ShowLoadingScreen(char *screen_name, int effect, int loading_steps)
SPRT prims[4];
POLY_FT3 nulls[4];
int fade_step;
if (effect == 1)
SetDispMask(0);
@ -282,6 +282,13 @@ void ShowLoadingScreen(char *screen_name, int effect, int loading_steps)
SetupDefDispEnv(&load_disp, 0, 0, 320, 512);
load_draw.dfe = 1;
#ifndef PSX
load_draw.clip.x = 0;
load_draw.clip.y = 0;
load_draw.clip.w = 320;
load_draw.clip.h = 512;
load_disp.isinter = 1;
#endif
PutDispEnv(&load_disp);
PutDrawEnv(&load_draw);

View File

@ -1152,7 +1152,7 @@ void StepSim(void)
static char t2; // offset 0x5
static int oldsp; // offset 0x8
char padSteer;
char padAcc;
short* playerFelony;
int stream;
CAR_DATA* cp;
@ -1412,18 +1412,17 @@ void StepSim(void)
{
if (Pads[stream].type == 4)
{
padSteer = Pads[stream].mapanalog[3];
padAcc = Pads[stream].mapanalog[3];
if (padSteer < -64 && padSteer > -100)
// walk back
if (padAcc < -64)
{
Pads[stream].mapped |= 0x1008;
if(padAcc < -100)
Pads[stream].mapped |= 0x1000;
else
Pads[stream].mapped |= 0x1008;
}
else if (padSteer < -100 && padSteer > 127)
{
stream = pl->padid;
Pads[stream].mapped |= 0x1000;
}
else if (padSteer > 32)
else if (padAcc > 32)
{
stream = pl->padid;
Pads[stream].mapped |= 0x4000;
@ -2374,7 +2373,7 @@ void PrintCommandLineArguments()
#endif // DEBUG_OPTIONS
" -replay <filename> : starts replay from file\n"
#ifdef CUTSCENE_RECORDER
" -recordcutscene : starts cutscene recording session\n"
" -recordcutscene <filename> : starts cutscene recording session. Specify INI filename with it\n"
#endif
" -nointro : disable intro screens\n"
" -nofmv : disable all FMVs\n";
@ -2616,9 +2615,10 @@ int redriver2_main(int argc, char** argv)
gInFrontend = 0;
AttractMode = 0;
extern void LoadCutsceneRecorder();
extern void LoadCutsceneRecorder(char* filename);
LoadCutsceneRecorder();
LoadCutsceneRecorder(argv[i+1]);
i++;
}
#endif
else

View File

@ -797,10 +797,11 @@ void ControlMap(void)
UnpackRegion(region_to_unpack, region_x & 1U | (region_z & 1U) * 2); // is that ever valid for 'target_barrel_region'?
current_region = region_to_unpack;
CheckUnpackNewRegions();
CheckLoadAreaData(current_barrel_region_xcell, current_barrel_region_zcell);
CheckUnpackNewRegions();
current_cell_x = (camera_position.vx + units_across_halved) / MAP_CELL_SIZE;
current_cell_z = (camera_position.vz + units_down_halved) / MAP_CELL_SIZE;

View File

@ -3,10 +3,8 @@
#include "PRES.H"
#include "MISSION.H"
#include "OVERMAP.H"
#include "PRES.H"
#include "CUTSCENE.H"
#include "GLAUNCH.H"
#include "MDRAW.H"
#include "OVERLAY.H"
#include "REPLAYS.H"
#include "PAUSE.H"
@ -600,6 +598,7 @@ void DrawWorldTarget(MS_TARGET *target)
tv.vz = target->data[4];
tv.vy = 10000;
// Capture the Flag target properties
switch(target->data[1] & 0x30000)
{
case 0x20000:
@ -743,6 +742,7 @@ void DrawMultiplayerTarget(MS_TARGET *target)
tv.vz = target->data[4];
tv.vy = 10000;
// Capture the Flag target properties
switch(target->data[1] & 0x30000)
{
case 0x10000:

View File

@ -29,6 +29,7 @@
#include <string.h>
#ifndef PSX
#include <stdint.h>
#include <SDL.h>
#endif // PSX
@ -288,6 +289,19 @@ void InitialiseMissionDefaults(void)
last_flag = -1;
ClearMem((char *)reservedSlots, sizeof(reservedSlots));
#ifdef CUTSCENE_RECORDER
// [A] reserve slots to avoid their use for chases
extern int gCutsceneAsReplay;
if (gCutsceneAsReplay)
{
extern int gCutsceneAsReplay_ReserveSlots;
for (int i = 0; i < gCutsceneAsReplay_ReserveSlots; i++)
reservedSlots[i] = 1;
}
#endif // CUTSCENE_RECORDER
cop_adjust = 0;
playercollected[0] = 0;
playercollected[1] = 0;
@ -3376,6 +3390,12 @@ int MRRequestCar(MS_TARGET *target)
// [D] [T]
void MRHandleCarRequests(void)
{
#ifdef CUTSCENE_RECORDER
extern int gCutsceneAsReplay;
if (gCutsceneAsReplay != 0)
return;
#endif
if (Mission.CarTarget)
MRCreateCar(Mission.CarTarget);
}

View File

@ -49,6 +49,36 @@ unsigned short *Low2LowerDetailTable = NULL;
/* end block 3 */
// End Line: 79
// [A]
int staticModelSlotBitfield[48];
// [A] returns freed slot count
int CleanSpooledModelSlots()
{
int i;
int num_freed;
num_freed = 0;
// assign model pointers
for (i = 0; i < MAX_MODEL_SLOTS; i++) // [A] bug fix. Init with dummyModel
{
// if bit does not indicate usage - reset to dummy model
if((staticModelSlotBitfield[i >> 5] & 1 << (i & 31)) == 0)
{
if(modelpointers[i] != &dummyModel)
{
modelpointers[i] = &dummyModel;
pLodModels[i] = &dummyModel;
num_freed++;
}
}
}
return num_freed;
}
// [D] [T]
void ProcessMDSLump(char *lump_file, int lump_size)
{
@ -62,6 +92,9 @@ void ProcessMDSLump(char *lump_file, int lump_size)
mdsfile = (lump_file + 4);
num_models_in_pack = modelAmts;
// [A] usage bits
ClearMem((char*)staticModelSlotBitfield, sizeof(staticModelSlotBitfield));
// assign model pointers
for (i = 0; i < MAX_MODEL_SLOTS; i++) // [A] bug fix. Init with dummyModel
{
@ -74,8 +107,14 @@ void ProcessMDSLump(char *lump_file, int lump_size)
size = *(int*)mdsfile;
mdsfile += sizeof(int);
if (size)
modelpointers[i] = (MODEL*)mdsfile;
if (size)
{
// add the usage bit
staticModelSlotBitfield[i >> 5] |= 1 << (i & 31);
model = (MODEL*)mdsfile;
modelpointers[i] = model;
}
mdsfile += size;
}

View File

@ -14,6 +14,8 @@ extern unsigned short *Low2LowerDetailTable;
extern int num_models_in_pack;
extern int CleanSpooledModelSlots();
extern void ProcessMDSLump(char *lump_file, int lump_size); // 0x00064CFC
extern int ProcessCarModelLump(char *lump_ptr, int lump_size); // 0x00064E6C

File diff suppressed because it is too large Load Diff

View File

@ -16,23 +16,29 @@
#include "FELONY.H"
#include "SCORES.H"
#ifndef PSX
#include "EMULATOR.H"
#endif
COLOUR_BAND felonyColour[3] =
{
{ { 0u, 0u, 255u, 0u }, 0, 0 },
{ { 255u, 0u, 0u, 0u }, 659, 0 },
{ { 0u, 0u, 255u, 0u }, 4096, 2 }
{ { 0, 0, 255, 0 }, 0, 0 },
{ { 255, 0, 0, 0 }, 659, 0 },
{ { 0, 0, 255, 0 }, 4096, 2 }
};
COLOUR_BAND playerDamageColour[3] =
{
{ { 0u, 255u, 0u, 0u }, 0, 0 },
{ { 255u, 0u, 0u, 0u }, 3686, 0 },
{ { 0u, 0u, 0u, 0u }, 4096, 2 }
{ { 0, 255, 0, 0 }, 0, 0 },
{ { 255, 0, 0, 0 }, 3686, 0 },
{ { 0, 0, 0, 0 }, 4096, 2 }
};
COLOUR_BAND damageColour[2] =
{ { { 0u, 255u, 0u, 0u }, 0, 0 }, { { 255u, 0u, 0u, 0u }, 4096, 0 } };
{
{ { 0, 255, 0, 0 }, 0, 0 },
{ { 255, 0, 0, 0 }, 4096, 0 }
};
// decompiled code
// original method signature:
@ -57,51 +63,68 @@ PERCENTAGE_BAR FelonyBar;
PERCENTAGE_BAR ProxyBar;
int gDoOverlays = 1;
int gWidescreenOverlayAlign = 0; // [A] custom widescreen alignment by PSX hack
// [D]
#define PERCENTAGE_BAR_WIDTH 102
#define PERCENTAGE_BAR_HEIGHT 10
// [A]
int gOverlayXPos = 16;
int gOverlayXOppPos = 208;
// [D] [T]
void InitOverlays(void)
{
bool bVar1;
gDoOverlays = 1;
// [A] init defaults
gOverlayXPos = 16;
gOverlayXOppPos = 208;
gMapXOffset = 249;
gMapYOffset = 181;
InitPercentageBar(&PlayerDamageBar, MaxPlayerDamage[0], playerDamageColour, "Damage");
PlayerDamageBar.xpos = 0x10;
PlayerDamageBar.ypos = 0x18;
PlayerDamageBar.xpos = gOverlayXPos;
PlayerDamageBar.ypos = 24;
bVar1 = 1 < NumPlayers;
PlayerDamageBar.active = 1;
if (bVar1)
if (NumPlayers > 1)
{
InitPercentageBar(&Player2DamageBar, MaxPlayerDamage[1], playerDamageColour, "Damage");
Player2DamageBar.xpos = 0x10;
Player2DamageBar.ypos = 0x8c;
Player2DamageBar.xpos = gOverlayXPos;
Player2DamageBar.ypos = 140;
Player2DamageBar.active = 1;
}
else
{
Player2DamageBar.active = 0;
}
Player2DamageBar.active = (bVar1);
InitPercentageBar(&FelonyBar, 0x1000, felonyColour, "Felony");
FelonyBar.xpos = 0x10;
FelonyBar.ypos = 0x2e;
InitPercentageBar(&FelonyBar, 4096, felonyColour, "Felony");
FelonyBar.xpos = gOverlayXPos;
FelonyBar.ypos = 46;
FelonyBar.active = 0;
InitPercentageBar(&DamageBar, 1, damageColour, "Damage");
DamageBar.xpos = 0xd0;
DamageBar.ypos = 0x18;
DamageBar.xpos = gOverlayXOppPos;
DamageBar.ypos = 24;
DamageBar.flags = 1;
DamageBar.active = 0;
InitPercentageBar(&ProxyBar, TAIL_TOOFAR - TAIL_TOOCLOSE, felonyColour, "Proximity");
ProxyBar.xpos = 0x10;
ProxyBar.ypos = 0x2e;
ProxyBar.xpos = gOverlayXPos;
ProxyBar.ypos = 46;
ProxyBar.active = 0;
InitOverheadMap();
if (GameType == GAME_CAPTURETHEFLAG) {
if (GameType == GAME_CAPTURETHEFLAG)
{
PlayerDamageBar.active = 0;
Player2DamageBar.active = 0;
gInvincibleCar = 1;
}
}
@ -124,55 +147,76 @@ void InitOverlays(void)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void DisplayOverlays(void)
{
short *felony;
if (NoPlayerControl == 0 && gInGameCutsceneActive == 0 && gInGameCutsceneDelay == 0)
if (NoPlayerControl != 0 || gInGameCutsceneActive != 0 || gInGameCutsceneDelay != 0)
return;
if (NumPlayers > 1)
{
if (NumPlayers > 1)
if (CurrentPlayerView == 0)
return;
SetFullscreenDrawing();
}
UpdateFlashValue();
if (gShowMap == 0)
{
FastForward = 0;
if (!gDoOverlays)
return;
#ifndef PSX
if(gWidescreenOverlayAlign)
{
if (CurrentPlayerView == 0)
return;
// align to PSX-mapped screen coordinates
RECT16 emuViewport;
Emulator_GetPSXWidescreenMappedViewport(emuViewport);
SetFullscreenDrawing();
// recalc pos
gOverlayXPos = 16 + emuViewport.x;
gOverlayXOppPos = emuViewport.w - 16 - PERCENTAGE_BAR_WIDTH;
gMapXOffset = emuViewport.w - 16 - MAP_SIZE_W;
// set up
PlayerDamageBar.xpos = gOverlayXPos;
Player2DamageBar.xpos = gOverlayXPos;
FelonyBar.xpos = gOverlayXPos;
DamageBar.xpos = gOverlayXOppPos;
ProxyBar.xpos = gOverlayXPos;
}
#endif
UpdateFlashValue();
DrawPercentageBar(&PlayerDamageBar);
DrawPercentageBar(&Player2DamageBar);
DrawPercentageBar(&DamageBar);
DrawPercentageBar(&FelonyBar);
if (gShowMap == 0)
DrawDrivingGameOverlays();
DrawOverheadMap();
if (CopsCanSeePlayer)
{
FastForward = 0;
if (player[0].playerCarId < 0)
felony = &pedestrianFelony;
else
felony = &car_data[player[0].playerCarId].felonyRating;
if (!gDoOverlays)
return;
DrawPercentageBar(&PlayerDamageBar);
DrawPercentageBar(&Player2DamageBar);
DrawPercentageBar(&DamageBar);
DrawPercentageBar(&FelonyBar);
DrawDrivingGameOverlays();
DrawOverheadMap();
if (CopsCanSeePlayer)
{
if (player[0].playerCarId < 0)
felony = &pedestrianFelony;
else
felony = &car_data[player[0].playerCarId].felonyRating;
if (*felony > FELONY_MIN_VALUE)
DrawCopIndicators();
}
}
else
{
FastForward = 1;
DrawFullscreenMap();
if (*felony > FELONY_MIN_VALUE)
DrawCopIndicators();
}
}
else
{
FastForward = 1;
DrawFullscreenMap();
}
}
@ -213,7 +257,7 @@ void DisplayOverlays(void)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void SetFullscreenDrawing(void)
{
DR_ENV *drenv;
@ -222,7 +266,7 @@ void SetFullscreenDrawing(void)
drenv = (DR_ENV *)current->primptr;
drawenv.clip.x = 256;
SetDefDrawEnv((DRAWENV *)&drawenv, 0, current->draw.clip.y & 256, 320, 256);
SetDefDrawEnv(&drawenv, 0, current->draw.clip.y & 256, 320, 256);
SetDrawEnv(drenv, &drawenv);
@ -251,15 +295,15 @@ void SetFullscreenDrawing(void)
/* end block 3 */
// End Line: 1486
// [D]
// [D] [T]
void InitPercentageBar(PERCENTAGE_BAR *bar, int size, COLOUR_BAND *pColourBand, char *tag)
{
bar->xpos = 0x96;
bar->xpos = 150;
bar->ypos = 10;
bar->width = 0x66;
bar->height = 10;
bar->width = PERCENTAGE_BAR_WIDTH;
bar->height = PERCENTAGE_BAR_HEIGHT;
bar->position = 0;
bar->max = (ushort)size;
bar->max = size;
bar->pColourBand = pColourBand;
bar->flags = 0;
bar->tag = tag;
@ -287,11 +331,11 @@ void InitPercentageBar(PERCENTAGE_BAR *bar, int size, COLOUR_BAND *pColourBand,
/* end block 3 */
// End Line: 1528
// [D]
// [D] [T]
void EnablePercentageBar(PERCENTAGE_BAR *bar, int max)
{
bar->position = 0;
bar->max = (ushort)max;
bar->max = max;
bar->active = 1;
}
@ -331,16 +375,15 @@ void EnablePercentageBar(PERCENTAGE_BAR *bar, int max)
/* end block 2 */
// End Line: 896
// [D]
// [D] [T]
void DrawPercentageBar(PERCENTAGE_BAR *bar)
{
short sVar1;
short sVar3;
uint uVar4;
POLY_G4 *poly;
POLY_G4 *poly2;
short sVar5;
short sVar9;
int min_x;
int max_x;
int min_y;
int max_y;
CVECTOR temp;
if (bar->active == 0)
@ -353,69 +396,75 @@ void DrawPercentageBar(PERCENTAGE_BAR *bar)
if (bar->max == 0)
{
sVar5 = bar->xpos;
uVar4 = bar->flags;
sVar9 = sVar5;
min_x = bar->xpos;
max_x = min_x;
}
else
{
uVar4 = bar->flags;
if ((uVar4 & 1) == 0)
if (bar->flags & 1)
{
sVar5 = bar->xpos;
sVar9 = sVar5 + ((bar->width * bar->position) / bar->max);
max_x = bar->xpos + bar->width;
min_x = max_x - ((bar->width * bar->position) / bar->max);
}
else
{
sVar9 = bar->xpos + bar->width;
sVar5 = sVar9 - ((bar->width * bar->position) / bar->max);
min_x = bar->xpos;
max_x = min_x + ((bar->width * bar->position) / bar->max);
}
}
sVar1 = bar->ypos;
sVar3 = bar->ypos + bar->height;
min_y = bar->ypos;
max_y = bar->ypos + bar->height;
if ((uVar4 & 2) == 0)
// draw the colour band that fills the bar
if ((bar->flags & 2) == 0)
{
poly = (POLY_G4 *)current->primptr;
setPolyG4(poly);
SetColourByValue(bar->pColourBand, (bar->position << 0xc) / bar->max, &temp);
SetColourByValue(bar->pColourBand, (bar->position * 4096) / bar->max, &temp);
poly->r0 = temp.r;
poly->g0 = temp.g;
poly->b0 = temp.b;
poly->r1 = temp.r;
poly->g1 = temp.g;
poly->b1 = temp.b;
temp.r = temp.r >> 2;
temp.g = temp.g >> 2;
temp.b = temp.b >> 2;
temp.r = temp.r / 4;
temp.g = temp.g / 4;
temp.b = temp.b / 4;
poly->r2 = temp.r;
poly->g2 = temp.g;
poly->b2 = temp.b;
poly->r3 = temp.r;
poly->g3 = temp.g;
poly->x0 = sVar5;
poly->y0 = bar->ypos;
poly->x1 = sVar9;
poly->y1 = bar->ypos;
poly->x0 = min_x;
poly->y0 = min_y;
poly->x1 = max_x;
poly->y1 = min_y;
poly->b3 = temp.b;
poly->x2 = sVar5;
poly->x3 = sVar9;
poly->y2 = bar->ypos + bar->height;
poly->y3 = bar->ypos + bar->height;
poly->x2 = min_x;
poly->x3 = max_x;
poly->y2 = max_y;
poly->y3 = max_y;
addPrim((u_long*)(current->ot + 1), poly);
current->primptr += sizeof(POLY_G4);
}
// draw transparent part
min_x = bar->xpos;
max_x = bar->xpos + bar->width;
poly2 = (POLY_G4 *)current->primptr;
setPolyG4(poly2);
setSemiTrans(poly2,1);
poly2->x0 = bar->xpos;
poly2->x2 = bar->xpos;
poly2->x0 = min_x;
poly2->x2 = min_x;
poly2->r0 = 0;
poly2->g0 = 0;
poly2->b0 = 0;
@ -428,33 +477,34 @@ void DrawPercentageBar(PERCENTAGE_BAR *bar)
poly2->r3 = 100;
poly2->g3 = 100;
poly2->b3 = 100;
poly2->y0 = bar->ypos;
poly2->x1 = bar->xpos + bar->width;
poly2->y1 = bar->ypos;
poly2->x3 = bar->xpos + bar->width;
poly2->y2 = bar->ypos + bar->height;
poly2->y3 = bar->ypos + bar->height;
poly2->y0 = min_y;
poly2->x1 = max_x;
poly2->y1 = min_y;
poly2->x3 = max_x;
poly2->y2 = max_y;
poly2->y3 = max_y;
addPrim((u_long*)(current->ot+1), poly2);
current->primptr += sizeof(POLY_G4);
// draw contours
LINE_F4* lineF4 = (LINE_F4*)current->primptr;
setLineF4(lineF4);
lineF4->r0 = 80;
lineF4->g0 = 80;
lineF4->b0 = 80;
lineF4->x0 = bar->xpos - 1;
lineF4->y0 = bar->ypos - 1;
lineF4->x0 = min_x - 1;
lineF4->y0 = min_y - 1;
lineF4->x1 = bar->xpos + bar->width;
lineF4->y1 = bar->ypos - 1;
lineF4->x1 = max_x;
lineF4->y1 = min_y - 1;
lineF4->x2 = bar->xpos + bar->width;
lineF4->x3 = bar->xpos - 1;
lineF4->x2 = max_x;
lineF4->x3 = min_x - 1;
lineF4->y2 = bar->ypos + bar->height;
lineF4->y3 = bar->ypos + bar->height;
lineF4->y2 = max_y;
lineF4->y3 = max_y;
addPrim((u_long*)(current->ot + 1), lineF4);
current->primptr += sizeof(LINE_F4);
@ -465,25 +515,25 @@ void DrawPercentageBar(PERCENTAGE_BAR *bar)
lineF2->g0 = 80;
lineF2->b0 = 80;
lineF2->x0 = bar->xpos - 1;
lineF2->y0 = bar->ypos - 1;
lineF2->x0 = min_x - 1;
lineF2->y0 = min_y - 1;
lineF2->x1 = bar->xpos - 1;
lineF2->y1 = bar->ypos + bar->height;
lineF2->x1 = min_x - 1;
lineF2->y1 = max_y;
addPrim((u_long*)(current->ot + 1), lineF2);
current->primptr += sizeof(LINE_F2);
TransparencyOn(current->ot + 1, 0x20);
if (bar->tag != NULL)
{
SetTextColour(128, 128, 64);
if ((bar->flags & 1U) == 0)
PrintString(bar->tag, bar->xpos + 8, bar->ypos - 11);
PrintString(bar->tag, min_x + 8, min_y - 11);
else
PrintStringRightAligned(bar->tag, bar->xpos + bar->width - 8, bar->ypos - 11);
PrintStringRightAligned(bar->tag, max_x - 8, min_y - 11);
}
}
@ -528,22 +578,35 @@ void DrawPercentageBar(PERCENTAGE_BAR *bar)
/* end block 3 */
// End Line: 1179
// [D]
// [D] [T]
void DrawProximityBar(PERCENTAGE_BAR *bar)
{
int iVar3;
TILE *tile;
short total;
int min_x;
int max_x;
int min_y;
int max_y;
int half_width;
if (bar->active == 0)
return;
if (bar->position < TAIL_TOOCLOSE)
bar->position = TAIL_TOOCLOSE;
total = bar->position;
if (TAIL_TOOFAR < bar->position)
bar->position = TAIL_TOOFAR;
if (total < TAIL_TOOCLOSE)
total = TAIL_TOOCLOSE;
if (total > TAIL_TOOFAR)
total = TAIL_TOOFAR;
iVar3 = bar->position - TAIL_TOOCLOSE;
min_x = bar->xpos;
max_x = bar->xpos + bar->width;
min_y = bar->ypos;
max_y = bar->ypos + bar->height;
half_width = bar->width / 2;
tile = (TILE *)current->primptr;
setTile(tile);
@ -551,9 +614,9 @@ void DrawProximityBar(PERCENTAGE_BAR *bar)
tile->g0 = 16;
tile->b0 = 16;
tile->x0 = ((bar->width * iVar3) / (TAIL_TOOFAR - TAIL_TOOCLOSE) - 1) + bar->xpos;
tile->x0 = ((bar->width * (total - TAIL_TOOCLOSE)) / (TAIL_TOOFAR - TAIL_TOOCLOSE) - 1) + min_x;
tile->w = 2;
tile->y0 = bar->ypos;
tile->y0 = min_y;
tile->h = bar->height;
addPrim(current->ot + 1, tile);
@ -574,14 +637,14 @@ void DrawProximityBar(PERCENTAGE_BAR *bar)
poly2->g3 = 255;
poly2->b3 = 0;
poly2->x0 = bar->xpos;
poly2->y0 = bar->ypos;
poly2->x1 = bar->xpos + (bar->width / 2);
poly2->y1 = bar->ypos;
poly2->x2 = bar->xpos;
poly2->y2 = bar->ypos + bar->height;
poly2->x3 = bar->xpos + (bar->width / 2);
poly2->y3 = bar->ypos + bar->height;
poly2->x0 = min_x;
poly2->y0 = min_y;
poly2->x1 = min_x + half_width;
poly2->y1 = min_y;
poly2->x2 = min_x;
poly2->y2 = max_y;
poly2->x3 = min_x + half_width;
poly2->y3 = max_y;
addPrim(current->ot + 1, poly2);
current->primptr += sizeof(POLY_G4);
@ -602,14 +665,14 @@ void DrawProximityBar(PERCENTAGE_BAR *bar)
poly2->g3 = 0;
poly2->b3 = 0;
poly2->x0 = bar->xpos + (bar->width / 2);
poly2->y0 = bar->ypos;
poly2->x1 = bar->xpos + bar->width;
poly2->y1 = bar->ypos;
poly2->x2 = bar->xpos + (bar->width / 2);
poly2->y2 = bar->ypos + bar->height;
poly2->x3 = bar->xpos + bar->width;
poly2->y3 = bar->ypos + bar->height;
poly2->x0 = min_x + half_width;
poly2->y0 = min_y;
poly2->x1 = max_x;
poly2->y1 = min_y;
poly2->x2 = min_x + half_width;
poly2->y2 = max_y;
poly2->x3 = max_x;
poly2->y3 = max_y;
addPrim(current->ot + 1, poly2);
current->primptr += sizeof(POLY_G4);
@ -620,17 +683,17 @@ void DrawProximityBar(PERCENTAGE_BAR *bar)
lineF4->g0 = 80;
lineF4->b0 = 80;
lineF4->x0 = bar->xpos - 1;
lineF4->y0 = bar->ypos - 1;
lineF4->x0 = min_x - 1;
lineF4->y0 = min_y - 1;
lineF4->x1 = bar->xpos + bar->width;
lineF4->y1 = bar->ypos - 1;
lineF4->x1 = max_x;
lineF4->y1 = min_y - 1;
lineF4->x2 = bar->xpos + bar->width;
lineF4->x3 = bar->xpos - 1;
lineF4->x2 = max_x;
lineF4->x3 = min_x - 1;
lineF4->y2 = bar->ypos + bar->height;
lineF4->y3 = bar->ypos + bar->height;
lineF4->y2 = max_y;
lineF4->y3 = max_y;
addPrim((u_long*)(current->ot + 1), lineF4);
current->primptr += sizeof(LINE_F4);
@ -641,27 +704,25 @@ void DrawProximityBar(PERCENTAGE_BAR *bar)
lineF2->g0 = 80;
lineF2->b0 = 80;
lineF2->x0 = bar->xpos - 1;
lineF2->y0 = bar->ypos - 1;
lineF2->x0 = min_x - 1;
lineF2->y0 = min_y - 1;
lineF2->x1 = bar->xpos - 1;
lineF2->y1 = bar->ypos + bar->height;
lineF2->x1 = min_x - 1;
lineF2->y1 = max_y;
addPrim((u_long*)(current->ot + 1), lineF2);
current->primptr += sizeof(LINE_F2);
TransparencyOn(current->ot + 1, 0x20);
TransparencyOn(current->ot + 1, 0x20);
if (bar->tag != NULL)
{
SetTextColour(128, 128, 64);
if ((bar->flags & 1U) == 0)
PrintString(bar->tag, bar->xpos + 8, bar->ypos - 11);
PrintString(bar->tag, min_x + 8, min_y - 11);
else
PrintStringRightAligned(bar->tag, bar->xpos + bar->width - 8, bar->ypos - 11);
PrintStringRightAligned(bar->tag, max_x - 8, min_y - 11);
}
}
@ -694,40 +755,34 @@ void DrawProximityBar(PERCENTAGE_BAR *bar)
char OverlayFlashValue = 0;
// [D]
// [D] [T]
void SetColourByValue(COLOUR_BAND *pColourBand, int value, CVECTOR *pOut)
{
COLOUR_BAND *pCVar1;
COLOUR_BAND *pCVar2;
COLOUR_BAND *pPrevColourBand;
int iVar3;
int iVar4;
int temp;
int scale;
int inv;
pCVar2 = pColourBand + 1;
if (pColourBand[1].value < value)
pPrevColourBand = pColourBand + 1;
while (pPrevColourBand->value < value)
{
pCVar1 = pColourBand + 2;
do {
pCVar2 = pCVar1;
pCVar1 = pCVar2 + 1;
} while (pCVar2->value < value);
pColourBand++;
pPrevColourBand++;
}
if ((pCVar2->flags != 0) && (pCVar2->flags == 2))
{
iVar3 = OverlayFlashValue * (pCVar2->value - pCVar2[-1].value);
value = pCVar2[-1].value + (iVar3 >> 3);
}
if (pPrevColourBand->flags == 2)
scale = pColourBand->value + OverlayFlashValue * (pPrevColourBand->value - pColourBand->value) / 8;
else
scale = value;
iVar3 = pCVar2->value - pCVar2[-1].value;
iVar4 = ((value - pCVar2[-1].value) * 0x1000) / iVar3;
temp = ((scale - pColourBand->value) * 0x1000) / (pPrevColourBand->value - pColourBand->value);
iVar3 = 0x1000 - iVar4;
inv = 4096 - temp;
pOut->r = ((iVar3 * pCVar2[-1].colour.r + iVar4 * (pCVar2->colour).r) >> 0xc);
pOut->g = ((iVar3 * pCVar2[-1].colour.g + iVar4 * (pCVar2->colour).g) >> 0xc);
pOut->b = ((iVar3 * pCVar2[-1].colour.b + iVar4 * (pCVar2->colour).b) >> 0xc);
pOut->r = FIXED(inv * pColourBand->colour.r + temp * pPrevColourBand->colour.r);
pOut->g = FIXED(inv * pColourBand->colour.g + temp * pPrevColourBand->colour.g);
pOut->b = FIXED(inv * pColourBand->colour.b + temp * pPrevColourBand->colour.b);
}
@ -760,16 +815,12 @@ void SetColourByValue(COLOUR_BAND *pColourBand, int value, CVECTOR *pOut)
/* end block 4 */
// End Line: 2049
// [D] [A] - bugged
// [D] [T]
void TransparencyOn(void *potz, ushort tpage)
{
DR_TPAGE *null;
null = (DR_TPAGE*)current->primptr;
setDrawTPage(null, 1, 0, tpage); // [A] might be incorrect
// original mode:
//*(char *)((int)puVar2 + 3) = '\x01';
//puVar2[1] = (uint)tpage & 0x9ff | 0xe1000600;
setDrawTPage(null, 1, 0, tpage);
addPrim(potz, null);
current->primptr += sizeof(DR_TPAGE);
@ -812,24 +863,23 @@ void TransparencyOn(void *potz, ushort tpage)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D] [T]
void UpdateFlashValue(void)
{
int iVar1;
int iVar2;
uint uVar3;
iVar2 = CameraCnt;
int size;
int flash;
if (gShowMap != 0)
iVar2 = FrameCnt;
size = FrameCnt;
else
size = CameraCnt;
flash = size % 16;
iVar1 = iVar2;
uVar3 = iVar2 - (iVar1 >> 4) * 16 & 0xff;
OverlayFlashValue = uVar3;
if (7 < uVar3)
OverlayFlashValue = 16 - OverlayFlashValue;
if (flash > 7)
flash = 16 - flash;
OverlayFlashValue = flash;
}
@ -894,14 +944,13 @@ void UpdateFlashValue(void)
/* WARNING: Unknown calling convention yet parameter storage is locked */
// [D]
// [D] [T]
void DrawDrivingGameOverlays(void)
{
int iVar1;
int iVar2;
SCORE_ENTRY* table;
int x;
int i;
int y;
int y_00;
char string[32];
SetTextColour(128, 128, 64);
@ -909,115 +958,137 @@ void DrawDrivingGameOverlays(void)
switch (GameType)
{
case GAME_GETAWAY:
iVar1 = PrintString("Best: ", 0x10, 0x3c);
PrintScoreTableTime(iVar1 + 3, 0x3c, ScoreTables.GetawayTable[GameLevel][gSubGameNumber][0].time);
table = &ScoreTables.GetawayTable[GameLevel][gSubGameNumber][0];
x = PrintString("Best: ", 16, 60);
PrintScoreTableTime(x + 3, 60, table->time);
break;
case GAME_GATERACE:
if (NumPlayers != 1)
if (NumPlayers == 1)
{
y = PrintString("Gate:", 0x10, 0x24);
table = &ScoreTables.GateRaceTable[GameLevel][gSubGameNumber][0];
PrintStringRightAligned("Gate:", 270, 16);
sprintf(string, "%d / %d", gPlayerScore.items, 100);
PrintString(string, y + 3, 0x24);
y = PrintString("Gate:", 0x10, 0x96);
sprintf(string, "%d / %d", gPlayerScore.P2items, 100);
LAB_00015b28:
PrintString(string, y + 3, 0x96);
return;
PrintString(string, 273, 16);
x = PrintString("Best:", 16, 36);
PrintScoreTableTime(x + 3, 36, table->time);
x = PrintString("Gate:", 16, 0x34);
if (table->items == -1)
sprintf(string, "-");
else
sprintf(string, "%d", table->items);
PrintString(string, x + 3, 52);
}
table = &ScoreTables.GateRaceTable[GameLevel][gSubGameNumber][0];
PrintStringRightAligned("Gate:", 0x10e, 0x10);
sprintf(string, "%d / %d", gPlayerScore.items, 100);
PrintString(string, 0x111, 0x10);
y = PrintString("Best:", 0x10, 0x24);
PrintScoreTableTime(y + 3, 0x24, table->time);
y = PrintString("Gate:", 0x10, 0x34);
if (table->items == -1)
goto LAB_00015c00;
LAB_00015c20:
sprintf(string, "%d", table->items);
goto LAB_00015c2c;
else
{
x = PrintString("Gate:", 16, 36);
sprintf(string, "%d / %d", gPlayerScore.items, 100);
PrintString(string, x + 3, 36);
x = PrintString("Gate:", 16, 150);
sprintf(string, "%d / %d", gPlayerScore.P2items, 100);
PrintString(string, x + 3, 150);
}
break;
case GAME_CHECKPOINT:
if (NumPlayers != 1)
if (NumPlayers > 1)
{
y = PrintString("Checks", 0x10, 0x24);
x = PrintString("Checks", 16, 36);
sprintf(string, "%d/5", gPlayerScore.items);
PrintString(string, y + 3, 0x24);
y = PrintString("Checks", 0x10, 0x96);
PrintString(string, x + 3, 36);
x = PrintString("Checks", 16, 150);
sprintf(string, "%d/5", gPlayerScore.P2items);
goto LAB_00015b28;
PrintString(string, x + 3, 150);
}
else
{
table = &ScoreTables.CheckpointTable[GameLevel][gSubGameNumber][0];
PrintStringRightAligned("Checks", 270, 16);
table = &ScoreTables.CheckpointTable[GameLevel][gSubGameNumber][0];
PrintStringRightAligned("Checks", 0x10e, 0x10);
sprintf(string, "%d/5", gPlayerScore.items);
PrintString(string, 0x111, 0x10);
sprintf(string, "%d/5", gPlayerScore.items);
PrintString(string, 273, 16);
goto LAB_00015c88;
x = PrintString("Best:", 16, 36);
PrintScoreTableTime(x + 3, 36, table->time);
}
break;
case GAME_TRAILBLAZER:
table = &ScoreTables.TrailblazerTable[GameLevel][gSubGameNumber][0];
PrintStringRightAligned("Cones:", 0xfa, 0x10);
PrintStringRightAligned("Cones:", 250, 16);
sprintf(string, "%d / %d", gPlayerScore.items, 100);
PrintString(string, 0xfd, 0x10);
y = PrintString("Best", 0x10, 0x24);
PrintScoreTableTime(y + 3, 0x24, table->time);
y = PrintString("Cones:", 0x10, 0x34);
PrintString(string, 253, 16);
x = PrintString("Best", 16, 36);
PrintScoreTableTime(x + 3, 36, table->time);
x = PrintString("Cones:", 16, 52);
if (table->items != -1)
goto LAB_00015c20;
LAB_00015c00:
sprintf(string, "-");
LAB_00015c2c:
PrintString(string, y + 3, 0x34);
sprintf(string, "%d", table->items);
else
sprintf(string, "-");
PrintString(string, x + 3, 52);
break;
case GAME_SURVIVAL:
table = &ScoreTables.SurvivalTable[GameLevel][gSubGameNumber][0];
LAB_00015c88:
y = PrintString("Best:", 0x10, 0x24);
PrintScoreTableTime(y + 3, 0x24, table->time);
x = PrintString("Best:", 16, 36);
PrintScoreTableTime(x + 3, 36, table->time);
break;
case GAME_CAPTURETHEFLAG:
y = PrintString("Flags:", 0x10, 0x10);
x = PrintString("Flags:", 16, 16);
sprintf(string, "%d", gPlayerScore.items);
PrintString(string, y + 3, 0x10);
y = PrintString("Flags:", 0x10, 0x84);
PrintString(string, x + 3, 16);
x = PrintString("Flags:", 16, 132);
sprintf(string, "%d", gPlayerScore.P2items);
PrintString(string, y + 3, 0x84);
PrintString(string, x + 3, 132);
break;
case GAME_SECRET:
y_00 = 0x24;
y = 0;
if (0 < gNumRaceTrackLaps)
{
do {
iVar2 = y + 1;
sprintf(string, "%s %d:", "Lap", iVar2);
iVar1 = PrintString(string, 0x10, y_00);
PrintScoreTableTime(iVar1 + 3, y_00, gLapTimes[0][y]);
y = iVar2;
y_00 = y_00 + 0x10;
} while (iVar2 < gNumRaceTrackLaps);
}
y = 36;
y = 0x96;
if ((1 < NumPlayers) && (y_00 = 0, 0 < gNumRaceTrackLaps))
i = 0;
do
{
do {
iVar2 = y_00 + 1;
sprintf(string, "%s %d:", "Lap", iVar2);
iVar1 = PrintString(string, 0x10, y);
PrintScoreTableTime(iVar1 + 3, y, gLapTimes[1][y_00]);
y_00 = iVar2;
y = y + 0x10;
} while (iVar2 < gNumRaceTrackLaps);
sprintf(string, "%s %d:", "Lap", i+1);
x = PrintString(string, 0x10, y);
PrintScoreTableTime(x + 3, y, gLapTimes[0][i]);
y += 16;
i++;
} while (i < gNumRaceTrackLaps);
if (NumPlayers > 1)
{
y = 150;
i = 0;
do
{
sprintf(string, "%s %d:", "Lap", i+1);
x = PrintString(string, 0x10, y);
PrintScoreTableTime(x + 3, y, gLapTimes[1][i]);
y += 16;
i++;
} while (i < gNumRaceTrackLaps);
}
break;
}
@ -1050,7 +1121,7 @@ void DrawDrivingGameOverlays(void)
/* end block 3 */
// End Line: 2407
// [D]
// [D] [T]
void PrintScoreTableTime(int x, int y, int time)
{
char string[32];

View File

@ -7,6 +7,9 @@ extern PERCENTAGE_BAR DamageBar;
extern PERCENTAGE_BAR FelonyBar;
extern PERCENTAGE_BAR ProxyBar;
extern int gDoOverlays;
extern int gWidescreenOverlayAlign;
extern char OverlayFlashValue;
extern void InitOverlays(); // 0x00014A58

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,12 @@
#ifndef OVERMAP_H
#define OVERMAP_H
extern unsigned short civ_clut[8][32][6];
#define MAP_SIZE_W 64
#define MAP_SIZE_H 60
extern int gMapXOffset;
extern int gMapYOffset;
extern int map_x_shift;
extern int map_z_shift;
@ -39,7 +44,7 @@ extern void LoadMapTile(int tpage, int x, int y); // 0x00018AA0
extern void SetMapPos(); // 0x00019A60
extern void draw_box(); // 0x00018BF4
extern void draw_box(int yPos, int h); // 0x00018BF4
extern void DrawN(VECTOR *pScreenPosition, int direct); // 0x00018D54

View File

@ -8,6 +8,7 @@
#include "CARS.H"
#include "CAMERA.H"
#include <stdint.h>
#include "SDL.h"
ushort distanceCache[16384];

File diff suppressed because it is too large Load Diff

View File

@ -69,7 +69,7 @@ pedFunc fpPedPersonalityFunctions[] = {
CivGetIn,
};
VECTOR tannerLookAngle = { 0, 0, 0, 0 };
SVECTOR tannerLookAngle = { 0, 0, 0, 0 };
const int tannerTurnMax = 16;
const int tannerTurnStep = 4;
@ -1434,11 +1434,16 @@ void DrawAllPedestrians(void)
if (PositionVisible((VECTOR*)&pPed->position) &&
FrustrumCheck((VECTOR*)&pPed->position, 60) != -1)
{
if (pPed->pedType <= OTHER_MODEL)
if (pPed->pedType == TANNER_MODEL)
{
if (!bKillTanner)
DrawTanner(pPed);
}
else if (pPed->pedType == OTHER_MODEL)
{
if (!bKillTanner)
DrawCharacter(pPed);
}
else if (pPed->pedType == OTHER_SPRITE)
{
DrawCharacter(pPed);
@ -2613,16 +2618,11 @@ void SetupTannerSitDown(PEDESTRIAN* pPed)
void TannerCameraHandler(PEDESTRIAN* pPed)
{
int value;
short extra;
int padSteer;
PLAYER* lcp;
int padid;
padid = pPed->padId;
lcp = &player[padid];
if (Pads[padid].type == 4)
{
padSteer = Pads[padid].mapanalog[0];
@ -2635,20 +2635,20 @@ void TannerCameraHandler(PEDESTRIAN* pPed)
value = padSteer;
if (padSteer < 0)
tannerLookAngle.vy = (value - 32) * -9;
tannerLookAngle.vy = (value - 32) * -11;
else
tannerLookAngle.vy = (value - 32) * 9;
tannerLookAngle.vy = (value - 32) * 11;
}
else
{
tannerLookAngle.vy = 0;
}
tannerLookAngle.vx = -Pads[padid].mapanalog[1];
tannerLookAngle.vx = -Pads[padid].mapanalog[1] * 2;
if (tannerLookAngle.vx < -32)
tannerLookAngle.vx = tannerLookAngle.vx - 128;
else if (tannerLookAngle.vx < 33)
if (tannerLookAngle.vx < -60)
tannerLookAngle.vx -= 128;
else if (tannerLookAngle.vx < 60)
tannerLookAngle.vx = 0;
}
else
@ -2658,33 +2658,7 @@ void TannerCameraHandler(PEDESTRIAN* pPed)
tannerLookAngle.vz = 0;
}
if (padd & 1)
{
if (padd & 2)
extra = 2048;
else
extra = 1024;
}
else
{
if (padd & 2)
extra = -1024;
else
extra = 0;
}
camera_position.vx = lcp->pos[0];
camera_position.vz = lcp->pos[2];
camera_angle.vx = camAngle.vx + tannerLookAngle.vx;
camera_angle.vy = (camAngle.vy - tannerLookAngle.vy) + extra & 0xfff;
camera_angle.vz = camAngle.vz + tannerLookAngle.vz;
tracking_car = 0;
lcp->cameraPos.vx = lcp->pos[0];
lcp->cameraPos.vy = camera_position.vy;
lcp->cameraPos.vz = lcp->pos[2];
// [A] old non-functioning code bloat removed
}

View File

@ -3,6 +3,8 @@
#define TANNER_COLLIDER_CARID (MAX_CARS)
extern SVECTOR tannerLookAngle;
extern MODEL* pmTannerModels[17];
extern MODEL* pmJerichoModels[6];

View File

@ -8,18 +8,18 @@
extern TEXTURE_DETAILS digit_texture;
FONT_DIGIT fontDigit[] = {
{ 2, 0xE },
{ 0x11, 0xE},
{ 0x20, 0x10},
{ 0x31, 0xF},
{ 0x41, 0xE },
{ 0x50, 0xE },
{ 4, 0x10 },
{ 0x15, 0xE },
{ 0x24, 0xF },
{ 0x34, 0x11 },
{ 0x46, 0xB },
{ 0x52, 7 },
{ 2, 14 },
{ 17, 14},
{ 32, 16},
{ 49, 15},
{ 65, 14 },
{ 80, 14 },
{ 4, 16 },
{ 21, 14 },
{ 36, 15 },
{ 52, 17 },
{ 70, 11 },
{ 82, 7 },
};
TEXTURE_DETAILS button_textures[11];
@ -111,7 +111,7 @@ void SetTextColour(unsigned char Red, unsigned char Green, unsigned char Blue)
// [D] [T]
int StringWidth(char *pString)
{
char let;
u_char let;
int w;
w = 0;
@ -781,7 +781,7 @@ void PrintStringBoxed(char *string, int ix, int iy)
wpt = word;
char c = 0;
u_char c = 0;
while ((c = *wpt++) != 0)
{

View File

@ -12,6 +12,7 @@
#include "CIV_AI.H"
#include "STRINGS.H"
#include "RAND.H"
char AnalogueUnpack[16] = {
0, -51, -63, -75, -87, -99, -111, -123,
@ -115,6 +116,9 @@ void InitPadRecording(void)
}
else
{
// reset stream count as cutscene/chase can increase it
NumReplayStreams = NumPlayers;
for (i = 0; i < NumReplayStreams; i++)
{
ReplayStreams[i].playbackrun = 0;
@ -174,9 +178,9 @@ int SaveReplayToBuffer(char *buffer)
header->magic = 0x14793209; // TODO: custom
header->GameLevel = GameLevel;
header->GameType = GameType;
header->NumReplayStreams = NumReplayStreams;
header->MissionNumber = gCurrentMissionNumber;
header->NumReplayStreams = NumReplayStreams - NumCutsceneStreams;
header->NumPlayers = NumPlayers;
header->CutsceneEvent = -1;
header->RandomChase = gRandomChase;
@ -297,6 +301,7 @@ int SaveReplayToBuffer(char *buffer)
int gCutsceneAsReplay = 0;
int gCutsceneAsReplay_PlayerId = 0;
int gCutsceneAsReplay_PlayerChanged = 0;
int gCutsceneAsReplay_ReserveSlots = 2;
char gCutsceneRecorderPauseText[64] = { 0 };
char gCurrentChasePauseText[64] = { 0 };
@ -378,17 +383,17 @@ int LoadCutsceneAsReplay(int subindex)
return 0;
}
void LoadCutsceneRecorder()
void LoadCutsceneRecorder(char* configFilename)
{
ini_t* config;
int loadExistingCutscene;
int subindex;
config = ini_load("cutscene_recorder.ini");
config = ini_load(configFilename);
if(!config)
{
printError("Unable to open 'cutscene_recorder.ini!'\n");
printError("Unable to open '%s'!\n", configFilename);
return;
}
@ -399,7 +404,12 @@ void LoadCutsceneRecorder()
ini_sget(config, "settings", "mission", "%d", &gCutsceneAsReplay);
ini_sget(config, "settings", "baseMission", "%d", &gCurrentMissionNumber);
ini_sget(config, "settings", "player", "%d", &gCutsceneAsReplay_PlayerId);
ini_sget(config, "settings", "reserveSlots", "%d", &gCutsceneAsReplay_ReserveSlots);
ini_sget(config, "settings", "subindex", "%d", &subindex);
// totally limited by streams
if(gCutsceneAsReplay_ReserveSlots > 8)
gCutsceneAsReplay_ReserveSlots = 8;
if(loadExistingCutscene)
{
@ -586,7 +596,25 @@ int LoadReplayFromBuffer(char *buffer)
return 1;
}
#ifndef PSX
int LoadUserAttractReplay(int mission, int userId)
{
char customFilename[64];
if (userId >= 0 && userId < gNumUserChases)
{
sprintf(customFilename, "REPLAYS\\User\\%s\\ATTRACT.%d", gUserReplayFolderList[userId], mission);
if (FileExists(customFilename))
{
if (Loadfile(customFilename, _other_buffer))
return LoadReplayFromBuffer(_other_buffer);
}
}
return 0;
}
#endif
// decompiled code
// original method signature:
@ -616,7 +644,26 @@ int LoadAttractReplay(int mission)
{
char filename[32];
sprintf(filename,"REPLAYS\\ATTRACT.%d", mission);
#ifndef PSX
int userId = -1;
// [A] REDRIVER2 PC - custom attract replays
if (gNumUserChases)
{
userId = rand() % (gNumUserChases + 1);
if (userId == gNumUserChases)
userId = -1;
}
if (LoadUserAttractReplay(mission, userId))
{
printInfo("Loaded custom attract replay (%d) by %s\n", mission, gUserReplayFolderList[userId]);
return 1;
}
#endif
sprintf(filename, "REPLAYS\\ATTRACT.%d", mission);
if (!FileExists(filename))
return 0;
@ -675,6 +722,10 @@ char GetPingInfo(char *cookieCount)
PingBufferPos++;
}
else
{
printInfo("-1 frame!\n");
}
return retCarId;
}
@ -685,21 +736,27 @@ char GetPingInfo(char *cookieCount)
// [A] Stores ping info into replay buffer
int StorePingInfo(int cookieCount, int carId)
{
#ifdef CUTSCENE_RECORDER
PING_PACKET* packet;
//extern int gCutsceneAsReplay;
if (gCutsceneAsReplay == 0)
return 0;
if (CurrentGameMode == GAMEMODE_REPLAY || gInGameChaseActive != 0)
return 0;
if(PingBuffer != NULL && PingBufferPos < MAX_REPLAY_PINGS)
{
packet = &PingBuffer[PingBufferPos++];
packet->frame = (CameraCnt - frameStart & 0xffffU);
packet->carId = carId;
packet->cookieCount = cookieCount;
return 1;
}
#endif
return 0;
}

View File

@ -1,6 +1,7 @@
#include "DRIVER2.H"
#ifndef PSX
#include <stdint.h>
#include <SDL.h>
#endif // !PSX
@ -110,7 +111,7 @@ int chunk_complete;
int new_area_location;
int LoadingArea = 0;
unsigned short *newmodels;
unsigned short *newmodels = NULL;
SPOOLQ spooldata[48];
@ -1168,6 +1169,8 @@ void InitSpooling(void)
ClearRegion(i);
}
CleanSpooledModelSlots();
newmodels = NULL;
spool_regioncounter = 0;
spoolerror = 0;
@ -1727,21 +1730,12 @@ void SetupModels(void)
// [D] [T]
void LoadInAreaModels(int area)
{
if (newmodels)
{
// clear old model ids
int nmodels = *newmodels;
unsigned short* new_model_numbers = newmodels + 1;
int num_freed;
// set old model ids to dummy
for (int i = 0; i < nmodels; i++)
{
int model_number = new_model_numbers[i];
modelpointers[model_number] = &dummyModel;
}
// [A] invalidate previously used spooled slots
num_freed = CleanSpooledModelSlots();
SPOOL_INFO("freed %d model slots\n", nmodels);
}
SPOOL_INFO("freed %d model slots\n", num_freed);
int length = AreaData[area].model_size;
newmodels = (ushort *)(model_spool_buffer + (length-1) * 2048);

View File

@ -1,12 +1,14 @@
#include "DRIVER2.H"
#ifndef PSX
#include <stdint.h>
#include <SDL.h>
#endif // !PSX
#include "LIBETC.H"
#include "SYSTEM.H"
#include "PLATFORM.H"
#include "XAPLAY.H"
#include "LOADVIEW.H"
#include "MISSION.H"
@ -14,7 +16,8 @@
#include "MAIN.H"
#include "PAD.H"
#include "DRAW.H"
#include <string.h>
#include "STRINGS.H"
#include "PLATFORM.H"
// Initialized in redriver2_main
char* _overlay_buffer = NULL; // 0x1C0000
@ -375,10 +378,7 @@ int Loadfile(char* name, char* addr)
int fileSize;
sprintf(namebuffer, "%s%s", gDataFolder, name);
#ifdef __unix__
fixslashes(namebuffer);
#endif
FixPathSlashes(namebuffer);
FILE* fptr = fopen(namebuffer, "rb");
if (!fptr)
@ -460,13 +460,10 @@ int LoadfileSeg(char* name, char* addr, int offset, int loadsize)
{
char namebuffer[64];
#ifndef PSX
int fileSize = 0;
int fileSize;
sprintf(namebuffer, "%s%s", gDataFolder, name);
#ifdef __unix__
fixslashes(namebuffer);
#endif
FixPathSlashes(namebuffer);
FILE* fptr = fopen(namebuffer, "rb");
if (!fptr)
@ -791,13 +788,10 @@ void loadsectors(char* addr, int sector, int nsectors)
// It has to be this way
void loadsectorsPC(char* filename, char* addr, int sector, int nsectors)
{
#ifdef __unix__
char namebuffer[64];
strcpy(namebuffer, filename);
fixslashes(namebuffer);
#else
char* namebuffer = filename;
#endif
FixPathSlashes(namebuffer);
FILE* fp = fopen(namebuffer, "rb");
@ -1003,7 +997,8 @@ void SwapDrawBuffers2(int player)
DrawSync(0);
if (player == 0) {
if (player == 0)
{
PutDispEnv(&current->disp);
}
@ -1265,6 +1260,8 @@ void SetupDrawBufferData(int num_players)
// [D] [T]
void InitaliseDrawEnv(DB* pBuff, int x, int y, int w, int h)
{
RECT16 clipRect;
SetDefDrawEnv(&pBuff[0].draw, x, y + 256, w, h);
SetDefDrawEnv(&pBuff[1].draw, x, y, w, h);
@ -1373,10 +1370,7 @@ void SetCityType(CITYTYPE type)
}
sprintf(filename, format, gDataFolder, LevelFiles[GameLevel]);
#ifdef __unix__
fixslashes(filename);
#endif
FixPathSlashes(filename);
FILE* levFp = fopen(filename, "rb");
@ -1384,6 +1378,7 @@ void SetCityType(CITYTYPE type)
{
char errPrint[1024];
sprintf(errPrint, "SetCityType: cannot open level '%s'\n", filename);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", errPrint, NULL);
return;
}
@ -1503,10 +1498,7 @@ int FileExists(char* filename)
char namebuffer[128];
sprintf(namebuffer, "%s%s", gDataFolder, filename);
#ifdef __unix__
fixslashes(namebuffer);
#endif
FixPathSlashes(namebuffer);
FILE* fp = fopen(namebuffer, "rb");
if (fp)

View File

@ -100,7 +100,7 @@ extern DB* current;
extern int citystart[8];
extern XYPAIR citylumps[8][4];
#ifdef PAL
#ifdef PAL_VERSION
#define draw_mode draw_mode_pal
#define video_mode MODE_PAL
#else

View File

@ -426,14 +426,10 @@ void DrawStopZone(VECTOR *pPosition)
pPoly->g0 = 64;
pPoly->b0 = 64;
pPoly->u0 = light_texture.coords.u0;
pPoly->v0 = light_texture.coords.v0;
pPoly->u1 = light_texture.coords.u1;
pPoly->v1 = light_texture.coords.v1;
pPoly->u2 = light_texture.coords.u2;
pPoly->v2 = light_texture.coords.v2;
pPoly->u3 = light_texture.coords.u3;
pPoly->v3 = light_texture.coords.v3;
*(ushort*)&pPoly->u0 = *(ushort*)&light_texture.coords.u0;
*(ushort*)&pPoly->u1 = *(ushort*)&light_texture.coords.u1;
*(ushort*)&pPoly->u2 = *(ushort*)&light_texture.coords.u2;
*(ushort*)&pPoly->u3 = *(ushort*)&light_texture.coords.u3;
if (gTimeOfDay == 3)
pPoly->tpage = light_texture.tpageid | 0x20;

View File

@ -735,11 +735,11 @@ void drawMesh(MVERTEX(*VSP)[5][5], int m, int n, _pct *pc)
gte_stotz(&z);
if (pc->flags & 0x6)
if (pc->flags & (PLOT_NO_CULL | PLOT_INV_CULL))
{
if (pc->flags & 0x4)
if (pc->flags & PLOT_NO_CULL)
opz = 1; // no culling
else
else // PLOT_FRONT_CULL
opz = -opz; // front face
}

View File

@ -5,11 +5,13 @@
#include "CAMERA.H"
#include "FMVPLAY.H"
#include "PAUSE.H"
#include "PLATFORM.H"
#include "SOUND.H"
#include "PRES.H"
#include "SYSTEM.H"
#ifndef PSX
#include "STRINGS.H"
#include "../utils/riff.h"
#include "../utils/audio_source/snd_al_source.h"
@ -49,6 +51,16 @@ static unsigned long buffer[8];
XA_TRACK XAMissionMessages[4];
#ifndef PSX
struct XA_SUBTITLE
{
char text[48];
int startframe;
int endframe;
};
XA_SUBTITLE gXASubtitles[30];
int gNumXASubtitles = 0;
int gXASubtitleTime = 0;
int gXASubtitlePauseTime = 0;
@ -63,12 +75,12 @@ void PrintXASubtitles()
int curTime = (VSync(-1) - gXASubtitleTime) * 17;
// find subtitles
for(int i = 0; i < g_wavData->m_numSubtitles; i++)
for(int i = 0; i < gNumXASubtitles; i++)
{
CUESubtitle_t* sub = &g_wavData->m_subtitles[i];
XA_SUBTITLE* sub = &gXASubtitles[i];
int subStartFrame = sub->sampleStart;
int subEndFrame = sub->sampleStart + sub->sampleLength;
int subStartFrame = sub->startframe;
int subEndFrame = sub->endframe;
if(curTime >= subStartFrame && curTime <= subEndFrame)
{
@ -342,11 +354,56 @@ void PlayXA(int num, int index)
{
char fileName[250];
sprintf(fileName, XANameFormat, gDataFolder, num+1, index);
FixPathSlashes(fileName);
g_wavData = new CSoundSource_WaveCache();
if (g_wavData->Load(fileName))
{
#if 0
// Save subtitles file
{
sprintf(fileName, "%sXA\\XABNK0%d.XA[%d].SBN", gDataFolder, num + 1, index);
fixslashes(fileName);
FILE* fp = fopen(fileName, "wb");
if (fp)
{
int numSubtitles = g_wavData->m_numSubtitles;
XA_SUBTITLE subtitles[30];
// save subtitle count
fwrite(&numSubtitles, sizeof(int), 1, fp);
for (int i = 0; i < numSubtitles; i++)
{
CUESubtitle_t* sub = &g_wavData->m_subtitles[i];
strcpy(subtitles[i].text, sub->text);
subtitles[i].startframe = sub->sampleStart;
subtitles[i].endframe = sub->sampleStart + sub->sampleLength;
}
// write all subtitles
fwrite(subtitles, sizeof(XA_SUBTITLE), numSubtitles, fp);
fclose(fp);
}
}
#else
// Load subtitles for XA
sprintf(fileName, "%sXA\\XABNK0%d.XA[%d].SBN", gDataFolder, num + 1, index);
FixPathSlashes(fileName);
FILE* fp = fopen(fileName, "rb");
if (fp)
{
fread(&gNumXASubtitles, sizeof(int), 1, fp);
fread(gXASubtitles, sizeof(XA_SUBTITLE), gNumXASubtitles, fp);
fclose(fp);
}
#endif
g_XAWave = new CSoundSource_OpenALCache(g_wavData);
alSourcei(g_XASource, AL_BUFFER, g_XAWave->m_alBuffer);

View File

@ -14,6 +14,7 @@
#define MAX_TRAFFIC_CARS 19
#define MAX_EXPLOSION_OBJECTS 5
#define MAX_THROWN_BOMBS 5
#define MAX_MOTION_CAPTURE 24
// replay definitions.
// DO NOT EDIT, breaks compatibility!

View File

@ -16,6 +16,7 @@
#include "C/PRES.H"
#include "C/SOUND.H"
#include "C/DEBRIS.H"
#include "C/E3STUFF.H"
#include "C/FMVPLAY.H"
#include "C/SCORES.H"
#include "C/LOADSAVE.H"
@ -48,7 +49,7 @@ screenFunc fpUserFunctions[] = {
GamePlayScreen,
GameNameScreen,
CheatNumlayerSelect,
BonusGalleryScreen
};
char* gfxNames[4] = {
@ -108,73 +109,161 @@ char* CutSceneNames[28] =
"Credits",
};
static char* gameNames[64] = {
"Downtown",
"Wrigleyville",
"Necropolis De Colon",
"Capitolio",
"Downtown",
"Upper Strip",
"Centro",
"Copacabana",
"Greektown",
"Grant Park",
"Necropolis de Colon",
"Old Havana",
"Lakeside",
"Mid Strip",
"Copacabana",
"Santa Tereza",
"Downtown",
"Meigs Field",
"The Docks",
"Old Havana",
"North Vegas",
"Lakeside",
"Lagoa Rodrigo de Freitas",
"Praca da Bandeira",
"Grant Park",
"Downtown",
"Old Havana",
"Vedado",
"Downtown",
"Upper Strip",
"Leblon",
"Praca da Bandeira",
"Ukrainian Village",
"Downtown",
"Vedado",
"Necropolis de Colon",
"Mid Strip",
"Downtown",
"Copacabana",
"Centro",
"Cabrini Green",
"River North",
"Old Havana",
"Plaza",
"Lakes",
"Ghost Town",
"Flamengo",
"Centro",
"River North",
"Cabrini Green",
"Plaza",
"Old Havana",
"Downtown",
"Lakes",
"Centro",
"Flamengo",
"River North",
"Cabrini Green",
"Old Havana",
"Plaza de la Revolucion",
"Ghost Town",
"North Vegas",
"Centro",
#ifndef PSX
char *areaNames[4][8] = {
{
"Downtown",
"Wrigleyville",
"Greektown",
"Grant Park",
"Meigs Field",
"Ukrainian Village",
"River North",
"Cabrini Green",
},
{
"Necropolis de Colon",
"Capitolio",
"Old Havana",
"The Docks",
"Vedado",
"Plaza",
"Plaza de la Revolucion",
NULL,
},
{
"Downtown",
"Upper Strip",
"Lakeside",
"Mid Strip",
"North Vegas",
"Lakes",
"Ghost Town",
NULL,
},
{
"Centro",
"Copacabana",
"Santa Tereza",
"Lagoa Rodrigo de Freitas",
"Praca da Bandeira",
"Leblon",
"Flamengo",
NULL,
},
};
static char gameAreas[64] = {
// Getaway (0-6)
0, 1, // Downtown, Wrigleyville
0, 1, // Necropolis De Colon, Capitolio
0, 1, // Downtown, Upper Strip
0, 1, // Centro, Copacabana
// Gate race (8-14)
2, 3, // Greektown, Grant Park
0, 2, // Necropolis de Colon, Old Havana
2, 3, // Lakeside, Mid Strip
1, 2, // Copacabana, Santa Tereza
// Checkpoint (16-22)
0, 4, // Downtown, Meigs Field
3, 2, // The Docks, Old Havana
4, 2, // North Vegas, Lakeside
3, 4, // Lagoa Rodrigo de Freitas, Praca da Bandeira
// Trailblazer (24-30)
3, 0, // Grant Park, Downtown
2, 4, // Old Havana, Vedado
0, 1, // Downtown, Upper Strip
5, 4, // Leblon, Praca da Bandeira
// [MP] Cops 'n Robbers (32-38)
5, 0, // Ukrainian Village, Downtown
4, 0, // Vedado, Necropolis de Colon
3, 0, // Mid Strip, Downtown
1, 0, // Copacabana, Centro
// [MP] Capture the Flag (40-46)
7, 6, // Cabrini Green, River North
2, 5, // Old Havana, Plaza
5, 6, // Lakes, Ghost Town
6, 0, // Flamengo, Centro
// [MP] Take a Ride (48-54)
6, 7, // River North, Cabrini Green
5, 2, // Plaza, Old Havana
0, 5, // Downtown, Lakes
0, 6, // Centro, Flamengo
// [MP] Checkpoint (56-62)
6, 7, // River North, Cabrini Green
2, 6, // Old Havana, Plaza de la Revolucion
6, 4, // Ghost Town, North Vegas
0, 6, // Centro, Flamengo
};
#define AREA_NAME(level, index) areaNames[level][index]
#define GAMEMODE_AREA(level, offset, index) gameAreas[offset + level * 2 + index]
#define GAMEMODE_AREA_NAME(level, offset, index) AREA_NAME(level, GAMEMODE_AREA(level, offset, index))
#else
static char* gameNames[64] = {
// Getaway (0-6)
"Downtown", "Wrigleyville",
"Necropolis De Colon", "Capitolio",
"Downtown", "Upper Strip",
"Centro", "Copacabana",
// Gate race (8-14)
"Greektown", "Grant Park",
"Necropolis de Colon", "Old Havana",
"Lakeside", "Mid Strip",
"Copacabana", "Santa Tereza",
// Checkpoint (16-22)
"Downtown", "Meigs Field",
"The Docks", "Old Havana",
"North Vegas", "Lakeside",
"Lagoa Rodrigo de Freitas", "Praca da Bandeira",
// Trailblazer (24-30)
"Grant Park", "Downtown",
"Old Havana", "Vedado",
"Downtown", "Upper Strip",
"Leblon", "Praca da Bandeira",
// [MP] Cops 'n Robbers (32-38)
"Ukrainian Village", "Downtown",
"Vedado", "Necropolis de Colon",
"Mid Strip", "Downtown",
"Copacabana", "Centro",
// [MP] Capture the Flag (40-46)
"Cabrini Green", "River North",
"Old Havana", "Plaza",
"Lakes", "Ghost Town",
"Flamengo", "Centro",
// [MP] Take a Ride (48-54)
"River North", "Cabrini Green",
"Plaza", "Old Havana",
"Downtown", "Lakes",
"Centro", "Flamengo",
// [MP] Checkpoint (56-62)
"River North", "Cabrini Green",
"Old Havana", "Plaza de la Revolucion",
"Ghost Town", "North Vegas",
"Centro", "Flamengo",
};
#define AREA_NAME(level, index) "???"
#define GAMEMODE_AREA(level, offset, index) (0)
#define GAMEMODE_AREA_NAME(level, offset, index) gameNames[offset + level * 2 + index]
#endif
int CarAvailability[4][10] = {
{1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,0,0,0,0,0,0},
@ -337,7 +426,7 @@ void SetVariable(int var)
#ifdef PSX
if (CallMemoryCard(0x11, 0) == 0)
#else
if(LoadReplayFromFile("chase.d2rp") == 0) // [A] temporary
if(LoadReplayFromFile("CHASE.D2RP") == 0) // [A] temporary
#endif
{
ReInitFrontend();
@ -412,6 +501,12 @@ void SetVariable(int var)
GameType = GAME_IDLEDEMO;
gCurrentMissionNumber = (value + 400);
break;
case 14: // [A]
{
ShowBonusGallery();
LoadFrontendScreens();
}
}
}
@ -513,7 +608,6 @@ void LoadFrontendScreens(void)
DrawSync(0);
Loadfile("DATA\\FEFONT.BNK", (char*)&feFont);
//PadChecks(); // [A] there is a bug too
}
@ -790,7 +884,9 @@ void SetupScreenSprts(PSXSCREEN *pScr)
/* end block 3 */
// End Line: 3526
DR_MOVE In;
DR_MOVE Out;
RECT16 storeRect = { 768, 475, 255, 36 };
// [D] [T]
void DrawScreen(PSXSCREEN *pScr)
@ -798,7 +894,15 @@ void DrawScreen(PSXSCREEN *pScr)
char version_info[32];
int numBtnsToDraw;
int i;
#ifndef PSX
if (bRedrawFrontend)
{
// flush the old screen
//EndFrame();
bRedrawFrontend = 0;
}
#endif
for (i = 0; i < 6; i++)
addPrim(current->ot + 11, &BackgroundPolys[i]);
@ -815,12 +919,15 @@ void DrawScreen(PSXSCREEN *pScr)
{
numBtnsToDraw = pScr->numButtons;
}
#ifndef PSX
NewSelection(0);
#endif
for (i = 0; i < numBtnsToDraw; i++)
{
PSXBUTTON *button = &pScr->buttons[i];
int status = button->action >> 8;
#ifdef PSX
if (status != 5)
{
if (button == pCurrButton)
@ -864,6 +971,50 @@ void DrawScreen(PSXSCREEN *pScr)
}
}
}
#else
int draw = (status != 5);
if (button == pCurrButton)
{
RECT16 rect;
rect.x = pCurrButton->s_x;
rect.y = pCurrButton->s_y;
rect.w = 255;
rect.h = 36;
SetDrawMove(&Out, &rect, storeRect.x, storeRect.y);
addPrim(current->ot + 8, &Out);
setXY0(&HighlightSprt, rect.x, rect.y);
addPrim(current->ot + 6, &HighlightSprt);
addPrim(current->ot + 7, &HighlightDummy);
draw = 1;
}
if (draw)
{
if (status == 3)
{
FEPrintString(button->Name, button->x * 2 + button->w, button->y, 4, 32, 32, 32);
}
else
{
if (bMissionSelect && (i == 0 || i == 5) ||
bDoingCarSelect && (i == 0 || i == 2) ||
bInCutSelect && (i == 0 || i == 2))
{
FEPrintString(button->Name, button->x * 2 + button->w, button->y, 4, 124, 108, 40);
}
else
{
FEPrintString(button->Name, button->x * 2 + button->w, button->y, 4, 128, 128, 128);
}
}
}
#endif
}
#if defined(_DEBUG) || defined(DEBUG_OPTIONS)
@ -881,10 +1032,14 @@ void DrawScreen(PSXSCREEN *pScr)
addPrim(&current->ot[3], &extraDummy);
}
}
#ifdef PSX
else
{
EndFrame();
}
#else
EndFrame();
#endif
}
@ -1041,25 +1196,30 @@ void SetupExtraPoly(char *fileName, int offset, int offset2)
FEDrawCDicon();
Loadfile(fileName, _frontend_buffer + offset2);
setSprt(&extraSprt);
setXY0(&extraSprt, 100, 226);
setRGB0(&extraSprt, 128, 128, 128);
setUV0(&extraSprt, 0, 0);
setWH(&extraSprt, 255, 219);
setClut(&extraSprt, 960, 256);
rect.x = 896;
rect.y = 256;
rect.w = 64;
rect.h = 219;
LoadImage(&rect, (u_long *)(_frontend_buffer + offset2 + offset * 0x8000));
DrawSync(0);
VSync(0);
setPolyFT3(&extraDummy);
setXY3(&extraDummy, -1, -1, -1, -1, -1, -1);
setTPage(&extraDummy, 0, 0, 896, 256);
if(bDrawExtra == 0)
{
setSprt(&extraSprt);
setPolyFT3(&extraDummy);
setXY0(&extraSprt, 100, 226);
setRGB0(&extraSprt, 128, 128, 128);
setUV0(&extraSprt, 0, 0);
setWH(&extraSprt, 255, 219);
setClut(&extraSprt, 960, 256);
setXY3(&extraDummy, -1, -1, -1, -1, -1, -1);
setTPage(&extraDummy, 0, 0, 896, 256);
}
bDrawExtra = 1;
@ -1212,60 +1372,52 @@ void ReInitScreens(void)
/* end block 3 */
// End Line: 4370
DR_MOVE In;
DR_MOVE Out;
RECT16 storeRect = { 768, 475, 255, 36 };
// [D] [T]
void NewSelection(short dir)
int NewButton(short dir)
{
PSXBUTTON *pNewB;
RECT16 rect;
if (pCurrScreen->numButtons == 0)
{
#ifndef PSX
EndFrame(); //do not overflow draw buffers
#endif
return;
}
if (pCurrScreen->numButtons == 0)
return -1;
pNewB = pCurrButton;
int btn = 0;
// any buttons pressed?
if (dir != 0)
{
SetDrawMove(&In, &storeRect, pCurrButton->s_x, pCurrButton->s_y);
addPrim(current->ot+9, &In);
}
int btn = 0;
if ((dir & 0x1000) != 0)
{
btn = pCurrButton->u;
}
else if ((dir & 0x4000) != 0)
{
btn = pCurrButton->d;
}
else if ((dir & 0x8000) != 0)
{
btn = pCurrButton->l;
}
else if ((dir & 0x2000) != 0)
{
btn = pCurrButton->r;
}
if ((dir & 0x1000) != 0)
{
btn = pCurrButton->u;
}
else if ((dir & 0x4000) != 0)
{
btn = pCurrButton->d;
}
else if ((dir & 0x8000) != 0)
{
btn = pCurrButton->l;
}
else if ((dir & 0x2000) != 0)
{
btn = pCurrButton->r;
if (btn != 0)
{
FESound(3);
pNewB = &pCurrScreen->buttons[btn - 1];
}
}
pCurrButton = pNewB;
if (btn != 0)
{
FESound(3);
pNewB = &pCurrScreen->buttons[btn - 1];
}
rect.x = pNewB->s_x;
rect.y = pNewB->s_y;
#ifdef PSX
rect.x = pCurrButton->s_x;
rect.y = pCurrButton->s_y;
rect.w = 255;
rect.h = 36;
@ -1277,8 +1429,6 @@ void NewSelection(short dir)
addPrim(current->ot + 6, &HighlightSprt);
addPrim(current->ot + 7, &HighlightDummy);
pCurrButton = pNewB;
if ((pNewB->action >> 8) == 3) {
FEPrintString(pNewB->Name, pNewB->x * 2 + pNewB->w, pNewB->y, 4, 32, 32, 32);
}
@ -1293,8 +1443,19 @@ void NewSelection(short dir)
FEPrintString(pNewB->Name, pNewB->x * 2 + pNewB->w, pNewB->y, 4, 128, 128, 128);
}
}
#endif
return btn;
}
// [D] [T]
void NewSelection(short dir)
{
#ifdef PSX
NewButton(dir);
EndFrame();
#else
NewButton(dir);
#endif
}
@ -1417,12 +1578,10 @@ int HandleKeyPress(void)
{
if (ScreenDepth > 0)
{
if (!bDoneAllready) {
if (!bDoneAllready)
FESound(0);
}
else {
else
bDoneAllready = 0;
}
if (--ScreenDepth == 0)
{
@ -1580,7 +1739,52 @@ void PadChecks(void)
}
}
// [A] - was inlined in DoFrontEnd
void InitFrontend(void)
{
FEInitCdIcon();
ResetGraph(1);
SetDispMask(0);
bRedrawFrontend = 0;
gInFrontend = 1;
idle_timer = VSync(-1);
LoadFrontendScreens();
SetupBackgroundPolys();
SetupScreenSprts(&PsxScreens[0]);
}
// [A] - was inlined in DoFrontEnd
void InitDisplay(void)
{
SetDispMask(0);
ResetGraph(0);
SetFEDrawMode();
EnableDisplay();
#ifdef PSX
DrawScreen(pCurrScreen);
EndFrame();
NewSelection(0);
// REALLY make sure the screen is cleared
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
#endif
SetDispMask(1);
}
// decompiled code
// original method signature:
@ -1620,46 +1824,9 @@ void PadChecks(void)
// [D] [T]
void DoFrontEnd(void)
{
FEInitCdIcon();
InitFrontend();
InitDisplay();
ResetGraph(1);
SetDispMask(0);
bRedrawFrontend = 0;
gInFrontend = 1;
idle_timer = VSync(-1);
LoadFrontendScreens();
pCurrScreen = PsxScreens;
pCurrButton = PsxScreens[0].buttons;
SetupBackgroundPolys();
SetupScreenSprts(pCurrScreen);
SetDispMask(0);
ResetGraph(0);
SetFEDrawMode();
SetVideoMode(video_mode);
EnableDisplay();
DrawScreen(pCurrScreen);
EndFrame();
NewSelection(0);
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
SetDispMask(1);
do
{
PadChecks();
@ -1683,16 +1850,7 @@ void DoFrontEnd(void)
}
#ifndef PSX
if (bRedrawFrontend)
{
// flush the old screen
EndFrame();
bRedrawFrontend = 0;
}
DrawScreen(pCurrScreen);
NewSelection(0);
#else
if (bRedrawFrontend)
{
@ -1935,22 +2093,22 @@ int FEPrintString(char *string, int x, int y, int justification, int r, int g, i
FE_CHARDATA *pFontInfo;
SPRT *font;
char let;
unsigned char let;
font = (SPRT *)current->primptr;
if (justification & 4)
{
char *pString = string;
char c = 0;
unsigned char c = 0;
int w = 0;
while ((c = *pString++) != 0)
while ((c = *pString++) != 0)
{
if (c == ' ')
if (c == ' ')
w += 4;
else
else
w += feFont.CharInfo[c].w;
}
@ -3485,6 +3643,7 @@ int CutSceneCitySelectScreen(int bSetup)
LoadImage(&rect, (u_long *)_frontend_buffer);
DrawSync(0);
#ifdef PSX
DisplayOnScreenText();
@ -3848,12 +4007,14 @@ void DisplayScoreTable(void)
offset = 32;
else if (GameType == GAME_CAPTURETHEFLAG)
offset = 40;
else if (GameType == GAME_CHECKPOINT && NumPlayers == 2)
offset = 56;
else
offset = (GameType - 4U) * 8;
if (GameType != GAME_PURSUIT && GameType != GAME_SURVIVAL)
{
sprintf(text, "%s", gameNames[offset + GameLevel * 2 + GameNum]);
sprintf(text, "%s", GAMEMODE_AREA_NAME(GameLevel, offset, GameNum));
FEPrintStringSized(text, 420, 206, 0xc00, 2, otherCol.r, otherCol.g, otherCol.b);
}
@ -3868,7 +4029,7 @@ void DisplayScoreTable(void)
{
if (pSE[i].items != -1)
{
sprintf(text, "%d");
sprintf(text, "%d", pSE[i].items);
FEPrintString(text, 140, offset, 2, scoreCol.r, scoreCol.g, scoreCol.b);
}
}
@ -3913,9 +4074,12 @@ int ScoreScreen(int bSetup)
if (bSetup)
{
GameLevel = 0;
DisplayScoreTable();
bDoingScores = 1;
currSelIndex = 0;
return 0;
}
@ -3923,57 +4087,37 @@ int ScoreScreen(int bSetup)
{
if (currSelIndex == 0)
{
if (GameType != GAME_SURVIVAL && GameType != GAME_PURSUIT)
if (GameType == GAME_SURVIVAL || GameType == GAME_PURSUIT)
{
if (GameNum == 1)
{
GameNum = 0;
}
else
{
GameNum = 1;
GameLevel--;
if (GameLevel < 0)
GameLevel = 3;
}
DisplayScoreTable();
bRedrawFrontend = 1;
}
else
{
GameLevel--;
if (GameLevel < 0)
if (--GameLevel < 0)
GameLevel = 3;
GameNum = 0;
DisplayScoreTable();
bRedrawFrontend = 1;
}
else
{
GameNum ^= 1;
}
}
else
{
if (GameType != GAME_SURVIVAL && GameType != GAME_PURSUIT && GameNum == 0)
if (GameType == GAME_SURVIVAL || GameType == GAME_PURSUIT)
{
GameNum = 1;
DisplayScoreTable();
bRedrawFrontend = 1;
}
else
{
GameLevel++;
if (GameLevel > 3)
if (++GameLevel > 3)
GameLevel = 0;
GameNum = 0;
DisplayScoreTable();
bRedrawFrontend = 1;
}
else
{
GameNum ^= 1;
}
}
#ifdef PSX
DisplayScoreTable();
bRedrawFrontend = 1;
#endif
}
else if (fePad & 0x10)
{
@ -3982,7 +4126,7 @@ int ScoreScreen(int bSetup)
}
else if ((fePad & 0x1000) || (fePad & 0x4000))
{
currSelIndex = currSelIndex ^ 1;
currSelIndex ^= 1;
}
#ifndef PSX
@ -4284,11 +4428,11 @@ int CheatScreen(int bSetup)
0x121,
0x11E,
0x11F,
(40 & 0xFF) | (1 << 8)
0,
};
int hackLookup2[5] = {
0xC01, 0xC00, -1, -1, -1
0xC01, 0xC00, -1, -1, 0xE00
};
if (bSetup == 0)
@ -4439,77 +4583,6 @@ int CheatScreen(int bSetup)
return 0;
}
int g_GalleryImage = 0;
char* GalleryImageNames[] = {
"GFX\\GAL\\IMG1.TIM",
"GFX\\GAL\\IMG2.TIM",
"GFX\\GAL\\IMG3.TIM"
};
// [A]
int BonusGalleryScreen(int bSetup)
{
char tmpStr[64];
int imageChanged;
RECT16 rect;
imageChanged = 0;
if(bSetup)
{
bDoingScores = 1;
g_GalleryImage = 0;
imageChanged = 1;
}
if (fePad & 0x10)
{
// goint back
bDoingScores = 0;
LoadFrontendScreens();
//LoadBackgroundFile("DATA\\GFX.RAW");
}
else if(fePad & 0x8000)
{
imageChanged = 1;
g_GalleryImage--;
if (g_GalleryImage < 0)
g_GalleryImage = 2;
FESound(3);
}
else if(fePad & 0x2000)
{
imageChanged = 1;
g_GalleryImage++;
if (g_GalleryImage > 2)
g_GalleryImage = 0;
FESound(3);
}
if(imageChanged)
{
FEDrawCDicon();
LoadfileSeg(GalleryImageNames[g_GalleryImage], _overlay_buffer, 20, 0x4ff80);
LoadClut((u_long*)_overlay_buffer, 640, 511);
DrawSync(0);
setRECT16(&rect, 640, 0, 320, 511);
LoadImage(&rect, (u_long*)&_overlay_buffer[512]);
DrawSync(0);
}
//sprintf(tmpStr, "Gallery %d of %d", g_GalleryImage + 1, 3);
//FEPrintStringSized(tmpStr, 10, 10, 4, 0, 128, 64, 0 );
return 0;
}
// decompiled code
// original method signature:
@ -4646,18 +4719,18 @@ int GameNameScreen(int bSetup)
{
if (GameType == GAME_TAKEADRIVE && NumPlayers == 2)
offset = 0x30;
offset = 48;
else if (GameType == GAME_COPSANDROBBERS)
offset = 0x20;
offset = 32;
else if (GameType == GAME_CAPTURETHEFLAG)
offset = 0x28;
offset = 40;
else if (GameType == GAME_CHECKPOINT && NumPlayers == 2)
offset = 0x38;
offset = 56;
else
offset = (GameType - 4U) * 8;
sprintf(pCurrScreen->buttons[0].Name, gameNames[offset + GameLevel * 2]);
sprintf(pCurrScreen->buttons[1].Name, gameNames[offset + GameLevel * 2 + 1]);
strcpy(pCurrScreen->buttons[0].Name, GAMEMODE_AREA_NAME(GameLevel, offset, 0));
strcpy(pCurrScreen->buttons[1].Name, GAMEMODE_AREA_NAME(GameLevel, offset, 1));
}
return 0;

View File

@ -2,18 +2,34 @@
#define PLATFORM_H
#ifdef _WIN32
#include <direct.h>
#define HOME_ENV "USERPROFILE"
#elif defined (__unix__)
#include <sys/stat.h>
#define HOME_ENV "HOME"
#define _mkdir(str) mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
inline void fixslashes(char* pathbuff)
#include <direct.h>
#define HOME_ENV "USERPROFILE"
inline void FixPathSlashes(char* pathbuff)
{
while (*pathbuff)
{
if (*pathbuff == '\\') *pathbuff = '/';
if (*pathbuff == '/') // make windows-style path
*pathbuff = '\\';
pathbuff++;
}
}
#elif defined (__unix__)
#include <sys/stat.h>
#define HOME_ENV "HOME"
#define _mkdir(str) mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
inline void FixPathSlashes(char* pathbuff)
{
while (*pathbuff)
{
if (*pathbuff == '\\') // make unix-style path
*pathbuff = '/';
pathbuff++;
}
}

View File

@ -1,7 +1,7 @@
#ifndef VERSION_H
#define VERSION_H
#define GAME_VERSION_N "3.4 alpha"
#define GAME_VERSION_N "5.3 alpha"
#define GAME_TITLE "REDRIVER2"
#define GAME_VERSION GAME_TITLE " " GAME_VERSION_N

View File

@ -3,7 +3,6 @@
#if defined (_WINDOWS)
#include <windows.h>
#include <Dbghelp.h>
#include <tchar.h>
LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo);

View File

@ -3,10 +3,10 @@
#include "EMULATOR_VERSION.H"
#include "EMULATOR_GLOBALS.H"
#include "EMULATOR_PRIVATE.H"
#include "CRASHHANDLER.H"
#include "LIBETC.H"
#include "LIBPAD.H"
//#include <stdio.h>
//#include <string.h>
@ -15,11 +15,8 @@
#endif
#include <assert.h>
#if defined(NTSC_VERSION)
#define FIXED_TIME_STEP (1.0/60.0) // 60 FPS clock
#else
#define FIXED_TIME_STEP (1.0/50.0) // 50 FPS clock
#endif
#define FIXED_TIME_STEP_NTSC (1.0/60.0) // 60 FPS clock
#define FIXED_TIME_STEP_PAL (1.0/50.0) // 50 FPS clock
#define SWAP_INTERVAL 1
@ -29,6 +26,8 @@
#include <string.h>
#include <SDL.h>
#include "EMULATOR_TIMER.H"
SDL_Window* g_window = NULL;
TextureID vramTexture;
TextureID whiteTexture;
@ -45,8 +44,9 @@ SysCounter counters[3] = { 0 };
//std::thread counter_thread;
#endif
double g_swapTime;
timerCtx_t g_swapTimer;
int g_swapInterval = SWAP_INTERVAL;
int g_wireframeMode = 0;
int g_texturelessMode = 0;
int g_emulatorPaused = 0;
@ -232,8 +232,8 @@ static int Emulator_InitialiseSDL(char* windowName, int width, int height, int f
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
#elif defined(OGL)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
#endif
#if defined(OGL) || defined(OGLES)
@ -263,66 +263,35 @@ static int Emulator_InitialiseSDL(char* windowName, int width, int height, int f
return TRUE;
}
static int Emulator_InitialiseGLEW()
static int Emulator_InitialiseGLExt()
{
#if defined(GLEW)
GLenum err = gladLoadGL();
if (err == 0)
{
return FALSE;
}
const char* rend = (const char *) glGetString(GL_RENDERER);
const char* vendor = (const char *) glGetString(GL_VENDOR);
eprintf("*Video adapter: %s by %s\n", rend, vendor);
const char* versionStr = (const char *) glGetString(GL_VERSION);
eprintf("*OpenGL version: %s\n", versionStr);
const char* glslVersionStr = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
eprintf("*GLSL version: %s\n", glslVersionStr);
#endif
return TRUE;
}
#ifdef _WIN32
LARGE_INTEGER g_performanceFrequency;
LARGE_INTEGER g_clockStart;
#else
timeval g_timeStart;
#endif // _WIN32
void Emulator_InitHPCTimer()
{
#ifdef _WIN32
QueryPerformanceFrequency(&g_performanceFrequency);
#else
gettimeofday(&g_timeStart, NULL);
#endif // _WIN32
}
double Emulator_GetHPCTime(int reset = 0)
{
#ifdef _WIN32
LARGE_INTEGER curr;
QueryPerformanceCounter( &curr);
double value = double(curr.QuadPart - g_clockStart.QuadPart) / double(g_performanceFrequency.QuadPart);
if (reset)
g_clockStart = curr;
#else
timeval curr;
gettimeofday(&curr, NULL);
double value = (float(curr.tv_sec - g_timeStart.tv_sec) + 0.000001f * float(curr.tv_usec - g_timeStart.tv_usec));
if (reset)
g_timeStart = curr;
#endif // _WIN32
return value;
}
SDL_Thread* g_vblankThread = NULL;
SDL_mutex* g_vblankMutex = NULL;
volatile bool g_stopVblank = false;
volatile int g_vblanksDone = 0;
volatile int g_lastVblankCnt = 0;
timerCtx_t g_vblankTimer;
extern void(*vsync_callback)(void);
@ -330,6 +299,7 @@ int Emulator_DoVSyncCallback()
{
SDL_LockMutex(g_vblankMutex);
#if 1
int vblcnt = g_vblanksDone - g_lastVblankCnt;
static bool canDoCb = true;
@ -348,7 +318,7 @@ int Emulator_DoVSyncCallback()
canDoCb = true;
}
#endif
g_lastVblankCnt = g_vblanksDone;
if (g_swapInterval == 0)
@ -359,7 +329,6 @@ int Emulator_DoVSyncCallback()
g_lastVblankCnt += 1;
}
SDL_UnlockMutex(g_vblankMutex);
return g_vblanksDone;
@ -367,20 +336,28 @@ int Emulator_DoVSyncCallback()
int vblankThreadMain(void* data)
{
double vblankTime = Emulator_GetHPCTime();
Emulator_InitHPCTimer(&g_vblankTimer);
do
{
double delta = vblankTime + FIXED_TIME_STEP - Emulator_GetHPCTime();
if (delta < 0)
const long vmode = GetVideoMode();
const double timestep = vmode == MODE_NTSC ? FIXED_TIME_STEP_NTSC : FIXED_TIME_STEP_PAL;
double delta = Emulator_GetHPCTime(&g_vblankTimer, 0);
if (delta > timestep)
{
// do vblank events
SDL_LockMutex(g_vblankMutex);
g_vblanksDone++;
vblankTime = Emulator_GetHPCTime();// SDL_GetTicks();
Emulator_GetHPCTime(&g_vblankTimer, 1);
#if 0
if(vsync_callback)
vsync_callback();
#endif
SDL_UnlockMutex(g_vblankMutex);
}
} while (!g_stopVblank);
@ -390,7 +367,7 @@ int vblankThreadMain(void* data)
static int Emulator_InitialiseCore()
{
Emulator_InitHPCTimer();
Emulator_InitHPCTimer(&g_swapTimer);
g_vblankThread = SDL_CreateThread(vblankThreadMain, "vbl", NULL);
@ -407,18 +384,13 @@ static int Emulator_InitialiseCore()
return FALSE;
}
g_swapTime = Emulator_GetHPCTime();
return TRUE;
}
void Emulator_Initialise(char* windowName, int width, int height, int fullscreen)
{
eprintf("Initialising Emulator.\n");
eprintf("VERSION: %d.%d\n", EMULATOR_MAJOR_VERSION, EMULATOR_MINOR_VERSION);
eprintf("Compile Date: %s Time: %s\n", EMULATOR_COMPILE_DATE, EMULATOR_COMPILE_TIME);
eprintf("Initialising Psy-X %d.%d\n", EMULATOR_MAJOR_VERSION, EMULATOR_MINOR_VERSION);
eprintf("Build date: %s:%s\n", EMULATOR_COMPILE_DATE, EMULATOR_COMPILE_TIME);
if (Emulator_InitialiseSDL(windowName, width, height, fullscreen) == FALSE)
{
@ -427,16 +399,16 @@ void Emulator_Initialise(char* windowName, int width, int height, int fullscreen
}
#if defined(GLEW)
if (Emulator_InitialiseGLEW() == FALSE)
if (Emulator_InitialiseGLExt() == FALSE)
{
eprinterr("Failed to Intialise GLEW\n");
eprinterr("Failed to Intialise GL extensions\n");
Emulator_ShutDown();
}
#endif
if (Emulator_InitialiseCore() == FALSE)
{
eprinterr("Failed to Intialise Emulator Core.\n");
eprinterr("Failed to Intialise Psy-X Core.\n");
Emulator_ShutDown();
}
@ -950,18 +922,20 @@ GLint u_Projection3D;
" fragColor.xyz += vec3(dither[dc.x][dc.y] * v_texcoord.w);\n"
#define GPU_SAMPLE_TEXTURE_4BIT_FUNC\
" // returns 16 bit colour\n"\
" float samplePSX(vec2 tc){\n"\
" vec2 uv = (tc * vec2(0.25, 1.0) + v_page_clut.xy) * vec2(1.0 / 1024.0, 1.0 / 512.0);\n"\
" vec2 comp = VRAM(uv);\n"\
" int index = int(fract(tc.x / 4.0) * 4.0);\n"\
" float v = comp[index / 2] * (255.0 / 16.0);\n"\
" float f = floor(v);\n"\
" vec2 c = vec2( (v - f) * 16.0, f );\n"\
" vec2 clut_pos = v_page_clut.zw;\n"\
" clut_pos.x += mix(c[0], c[1], fract(float(index) / 2.0) * 2.0) / 1024.0;\n"\
" return packRG(VRAM(clut_pos));\n"\
" }\n"
" // returns 16 bit colour\n"\
" float samplePSX(vec2 tc){\n"\
" vec2 uv = (tc * vec2(0.25, 1.0) + v_page_clut.xy) * vec2(1.0 / 1024.0, 1.0 / 512.0);\n"\
" vec2 comp = VRAM(uv);\n"\
" int index = int(fract(tc.x / 4.0 + 0.0001) * 4.0);\n"\
" float v = comp[index / 2] * (255.0 / 16.0);\n"\
" float f = floor(v);\n"\
" vec2 c = vec2( (v - f) * 16.0, f );\n"\
" vec2 clut_pos = v_page_clut.zw;\n"\
" clut_pos.x += mix(c[0], c[1], mod(index, 2)) / 1024.0;\n"\
" clut_pos.x += 0.0001;\n"\
" clut_pos.y += 0.0001;\n"\
" return packRG(VRAM(clut_pos));\n"\
" }\n"
#define GPU_SAMPLE_TEXTURE_8BIT_FUNC\
" // returns 16 bit colour\n"\
@ -1379,10 +1353,11 @@ void Emulator_Perspective3D(const float fov, const float width, const float heig
void Emulator_SetupClipMode(const RECT16& rect)
{
bool enabled = rect.x - activeDispEnv.disp.x > 0 ||
// [A] isinterlaced dirty hack for widescreen
bool enabled = activeDispEnv.isinter || (rect.x - activeDispEnv.disp.x > 0 ||
rect.y - activeDispEnv.disp.y > 0 ||
rect.w < activeDispEnv.disp.w - 1 ||
rect.h < activeDispEnv.disp.h - 1;
rect.h < activeDispEnv.disp.h - 1);
float psxScreenW = activeDispEnv.disp.w;
float psxScreenH = activeDispEnv.disp.h;
@ -1421,6 +1396,24 @@ void Emulator_SetupClipMode(const RECT16& rect)
#endif
}
void Emulator_GetPSXWidescreenMappedViewport(RECT16& rect)
{
float emuScreenAspect = float(windowWidth) / float(windowHeight);
float psxScreenW = activeDispEnv.disp.w;
float psxScreenH = activeDispEnv.disp.h;
rect.x = activeDispEnv.screen.x;
rect.y = activeDispEnv.screen.y;
rect.w = psxScreenW * emuScreenAspect * PSX_SCREEN_ASPECT; // windowWidth;
rect.h = psxScreenH; // windowHeight;
rect.x -= (rect.w - activeDispEnv.disp.w) / 2;
rect.w += rect.x;
}
void Emulator_SetShader(const ShaderID &shader)
{
#if defined(OGL) || defined(OGLES)
@ -1479,6 +1472,7 @@ extern void Emulator_Clear(int x, int y, int w, int h, unsigned char r, unsigned
{
// TODO clear rect if it's necessary
#if defined(OGL) || defined(OGLES)
glClearColor(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
@ -1715,7 +1709,6 @@ void Emulator_DoPollEvent()
}
bool begin_scene_flag = false;
bool vbo_was_dirty_flag = false;
bool Emulator_BeginScene()
{
@ -1908,19 +1901,21 @@ void Emulator_SwapWindow()
void Emulator_WaitForTimestep(int count)
{
const long vmode = GetVideoMode();
const double timestep = vmode == MODE_NTSC ? FIXED_TIME_STEP_NTSC : FIXED_TIME_STEP_PAL;
// additional wait for swap
if (g_swapInterval > 0)
{
double curTime;
double waitTime = FIXED_TIME_STEP * count;
double delta;
do
{
SDL_Delay(0); // yield
curTime = Emulator_GetHPCTime();
} while (curTime - g_swapTime < waitTime);
}
delta = Emulator_GetHPCTime(&g_swapTimer, 0);
} while (delta < timestep * count);
g_swapTime = Emulator_GetHPCTime();
Emulator_GetHPCTime(&g_swapTimer, 1);
}
}
void Emulator_EndScene()
@ -1928,9 +1923,6 @@ void Emulator_EndScene()
if (!begin_scene_flag)
return;
if (!vbo_was_dirty_flag)
return;
assert(begin_scene_flag);
if (g_wireframeMode)
@ -1943,7 +1935,6 @@ void Emulator_EndScene()
#endif
begin_scene_flag = false;
vbo_was_dirty_flag = false;
Emulator_SwapWindow();
}
@ -2095,8 +2086,6 @@ void Emulator_UpdateVertexBuffer(const Vertex *vertices, int num_vertices)
#else
#error
#endif
vbo_was_dirty_flag = true;
}
void Emulator_DrawTriangles(int start_vertex, int triangles)

View File

@ -36,11 +36,11 @@
#if defined(__ANDROID__)
#include <android/log.h>
#define LOG_TAG_EMU "[EMU] "
#define LOG_TAG_EMU "[PsyX] "
#define eprintf(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG_EMU, fmt, ##__VA_ARGS__)
#define eprinterr(fmt, ...) eprintf("[%s] - " fmt, FUNCNAME, ##__VA_ARGS__);
#else
#define eprintf(fmt, ...) printf("[EMU] " fmt, ##__VA_ARGS__)
#define eprintf(fmt, ...) printf("[Psy-X] " fmt, ##__VA_ARGS__)
#define eprinterr(fmt, ...) eprintf("[%s] - " fmt, FUNCNAME, ##__VA_ARGS__);
#endif
@ -201,6 +201,8 @@ extern void Emulator_SetPolygonOffset(float ofs);
extern void Emulator_SetStencilMode(int drawPrim);
extern void Emulator_EnableDepth(int enable);
extern void Emulator_GetPSXWidescreenMappedViewport(RECT16& rect);
extern void Emulator_LineSwapSourceVerts(VERTTYPE* &p0, VERTTYPE* &p1, unsigned char* &c0, unsigned char* &c1);
extern void Emulator_GenerateLineArray(struct Vertex* vertex, VERTTYPE* p0, VERTTYPE* p1, ushort gteidx);
extern void Emulator_GenerateVertexArrayTriangle(struct Vertex* vertex, VERTTYPE* p0, VERTTYPE* p1, VERTTYPE* p2, ushort gteidx);

View File

@ -2,7 +2,7 @@
#define EMULATOR_GLOBALS_H
#include <SDL_gamecontroller.h>
#include <EMULATOR.H>
#include "EMULATOR.H"
extern TextureID whiteTexture;
extern TextureID vramTexture;

View File

@ -37,7 +37,7 @@
#if defined(GLEW)
#define GL_GLEXT_PROTOTYPES 1
#include <glad.h>
#include "glad.h"
#endif
/*

View File

@ -2,6 +2,6 @@
#define EMULATOR_SETUP_H
//Disc image filename to load for disc image builds
#define DISC_IMAGE_FILENAME "TOMB5.CUE"
#define DISC_IMAGE_FILENAME "IMAGE.CUE"
#endif

View File

@ -0,0 +1,41 @@
#ifdef _WIN32
#include <windows.h>
#else
#include <stddef.h>
#endif // _WIN32
#include "EMULATOR_TIMER.H"
void Emulator_InitHPCTimer(timerCtx_t* timer)
{
#ifdef _WIN32
QueryPerformanceFrequency(&timer->performanceFrequency);
#else
gettimeofday(&timer->timeStart, NULL);
#endif // _WIN32
}
double Emulator_GetHPCTime(timerCtx_t* timer, int reset)
{
#ifdef _WIN32
LARGE_INTEGER curr;
QueryPerformanceCounter( &curr);
double value = double(curr.QuadPart - timer->clockStart.QuadPart) / double(timer->performanceFrequency.QuadPart);
if (reset)
timer->clockStart = curr;
#else
timeval curr;
gettimeofday(&curr, NULL);
double value = (float(curr.tv_sec - timer->timeStart.tv_sec) + 0.000001f * float(curr.tv_usec - timer->timeStart.tv_usec));
if (reset)
timer->timeStart = curr;
#endif // _WIN32
return value;
}

View File

@ -0,0 +1,24 @@
#ifndef EMULATOR_TIMER_H
#define EMULATOR_TIMER_H
#ifdef _WIN32
#include <profileapi.h>
#else
#include <sys/time.h>
#endif
struct timerCtx_t
{
#ifdef _WIN32
LARGE_INTEGER performanceFrequency;
LARGE_INTEGER clockStart;
#else
timeval timeStart;
#endif // _WIN32
};
extern void Emulator_InitHPCTimer(timerCtx_t* timer);
extern double Emulator_GetHPCTime(timerCtx_t* timer, int reset = 0);
#endif // EMULATOR_TIMER_H

View File

@ -6,7 +6,7 @@
/* Emulator version */
#define EMULATOR_MAJOR_VERSION (1)
#define EMULATOR_MINOR_VERSION (101)
#define EMULATOR_MINOR_VERSION (500)
/* Compile date and time */
#define EMULATOR_COMPILE_DATE (__DATE__)

View File

@ -5,6 +5,7 @@
#include <SDL_timer.h>
int vmode = MODE_NTSC;
void(*vsync_callback)(void) = NULL;
int StopCallback(void)
@ -15,8 +16,9 @@ int StopCallback(void)
int ResetCallback(void)
{
int old = (int)vsync_callback;
vsync_callback = NULL;
return 0;
return old;
}
extern unsigned int g_swapTime;
@ -44,26 +46,19 @@ int VSync(int mode)
int VSyncCallback(void(*f)(void))
{
int old = (int)vsync_callback;
vsync_callback = f;
return 0;
}
long GetVideoMode(void)
{
#ifdef NTSC_VERSION
return MODE_NTSC;
#else
return MODE_PAL;
#endif
return old;
}
long SetVideoMode(long mode)
{
UNIMPLEMENTED();
#ifdef NTSC_VERSION
return MODE_NTSC;
#else
return MODE_PAL;
#endif
int old = vmode;
vmode = mode;
return old;
}
long GetVideoMode()
{
return vmode;
}

View File

@ -8,7 +8,7 @@
#include <stdint.h>
#include <LIBETC.H>
#include "LIBETC.H"
#include <stdio.h>
#include <stdlib.h>
@ -246,7 +246,6 @@ int DrawSync(int mode)
drawsync_callback();
}
return 0;
}
@ -453,6 +452,8 @@ DRAWENV* SetDefDrawEnv(DRAWENV* env, int x, int y, int w, int h)//(F)
env->clip.x = x;
env->clip.y = y;
env->clip.w = w;
env->clip.h = h;
env->tw.x = 0;
env->tw.y = 0;
env->tw.w = 0;
@ -461,7 +462,6 @@ DRAWENV* SetDefDrawEnv(DRAWENV* env, int x, int y, int w, int h)//(F)
env->g0 = 0;
env->b0 = 0;
env->dtd = 1;
env->clip.h = h;
if (GetVideoMode() == 0)
{

Some files were not shown because too many files have changed in this diff Show More