mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-25 11:52:32 +01:00
Merge pull request #11 from OpenDriver2/develop-SoapyMan
General fixes and improvements
This commit is contained in:
commit
8e976e3b9e
@ -1,4 +1,4 @@
|
||||
version: 3.0.{build}
|
||||
version: 4.2.{build}
|
||||
|
||||
branches:
|
||||
only:
|
||||
@ -64,7 +64,7 @@ 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
|
||||
- cmd: xcopy /e /v %data_folder% .\ /Y
|
||||
- 7z a "REDRIVER2_%configuration%.zip" ".\*"
|
||||
|
||||
#build: off
|
||||
|
37
changelog.txt
Normal file
37
changelog.txt
Normal file
@ -0,0 +1,37 @@
|
||||
REDRIVER2 4.2 alpha
|
||||
|
||||
Changelog since Oct 12 2000
|
||||
|
||||
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"
|
||||
|
||||
Effects/Visuals:
|
||||
- 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
|
279
data/DRIVER2/DATA/CREDITS.ENG
Normal file
279
data/DRIVER2/DATA/CREDITS.ENG
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
data/DRIVER2/FMV/FONT.TIM
Normal file
BIN
data/DRIVER2/FMV/FONT.TIM
Normal file
Binary file not shown.
@ -11,5 +11,7 @@ bilinearFiltering=0
|
||||
pgxpZbuffer=0
|
||||
|
||||
[game]
|
||||
drawDistance=600
|
||||
freeCamera=1
|
||||
drawDistance=1200
|
||||
freeCamera=1
|
||||
driver1music=0
|
||||
userChases=RacingFreak,Snoopi,Olanov,Vortex,Fireboyd78
|
25
data/cutscene_recorder.ini
Normal file
25
data/cutscene_recorder.ini
Normal 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
|
@ -3,7 +3,6 @@
|
||||
|
||||
#if defined (_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <Dbghelp.h>
|
||||
#include <tchar.h>
|
||||
|
||||
LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo);
|
||||
|
@ -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>
|
||||
@ -29,6 +29,8 @@
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "EMULATOR_TIMER.H"
|
||||
|
||||
SDL_Window* g_window = NULL;
|
||||
TextureID vramTexture;
|
||||
TextureID whiteTexture;
|
||||
@ -45,8 +47,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;
|
||||
@ -276,53 +279,12 @@ static int Emulator_InitialiseGLEW()
|
||||
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 +292,7 @@ int Emulator_DoVSyncCallback()
|
||||
{
|
||||
SDL_LockMutex(g_vblankMutex);
|
||||
|
||||
#if 1
|
||||
int vblcnt = g_vblanksDone - g_lastVblankCnt;
|
||||
|
||||
static bool canDoCb = true;
|
||||
@ -348,7 +311,7 @@ int Emulator_DoVSyncCallback()
|
||||
|
||||
canDoCb = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
g_lastVblankCnt = g_vblanksDone;
|
||||
|
||||
if (g_swapInterval == 0)
|
||||
@ -359,7 +322,6 @@ int Emulator_DoVSyncCallback()
|
||||
g_lastVblankCnt += 1;
|
||||
}
|
||||
|
||||
|
||||
SDL_UnlockMutex(g_vblankMutex);
|
||||
|
||||
return g_vblanksDone;
|
||||
@ -367,20 +329,25 @@ 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)
|
||||
double delta = Emulator_GetHPCTime(&g_vblankTimer, 0);
|
||||
|
||||
if (delta > FIXED_TIME_STEP)
|
||||
{
|
||||
// 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 +357,7 @@ int vblankThreadMain(void* data)
|
||||
|
||||
static int Emulator_InitialiseCore()
|
||||
{
|
||||
Emulator_InitHPCTimer();
|
||||
Emulator_InitHPCTimer(&g_swapTimer);
|
||||
|
||||
g_vblankThread = SDL_CreateThread(vblankThreadMain, "vbl", NULL);
|
||||
|
||||
@ -407,10 +374,6 @@ static int Emulator_InitialiseCore()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
g_swapTime = Emulator_GetHPCTime();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -950,18 +913,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 +1344,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;
|
||||
@ -1479,6 +1445,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 +1682,6 @@ void Emulator_DoPollEvent()
|
||||
}
|
||||
|
||||
bool begin_scene_flag = false;
|
||||
bool vbo_was_dirty_flag = false;
|
||||
|
||||
bool Emulator_BeginScene()
|
||||
{
|
||||
@ -1911,16 +1877,15 @@ void Emulator_WaitForTimestep(int count)
|
||||
// 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 < FIXED_TIME_STEP * count);
|
||||
|
||||
g_swapTime = Emulator_GetHPCTime();
|
||||
Emulator_GetHPCTime(&g_swapTimer, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator_EndScene()
|
||||
@ -1928,9 +1893,6 @@ void Emulator_EndScene()
|
||||
if (!begin_scene_flag)
|
||||
return;
|
||||
|
||||
if (!vbo_was_dirty_flag)
|
||||
return;
|
||||
|
||||
assert(begin_scene_flag);
|
||||
|
||||
if (g_wireframeMode)
|
||||
@ -1943,7 +1905,6 @@ void Emulator_EndScene()
|
||||
#endif
|
||||
|
||||
begin_scene_flag = false;
|
||||
vbo_was_dirty_flag = false;
|
||||
|
||||
Emulator_SwapWindow();
|
||||
}
|
||||
@ -2095,8 +2056,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)
|
||||
|
37
src_rebuild/EMULATOR/EMULATOR_TIMER.C
Normal file
37
src_rebuild/EMULATOR/EMULATOR_TIMER.C
Normal file
@ -0,0 +1,37 @@
|
||||
#include <windows.h>
|
||||
#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;
|
||||
}
|
24
src_rebuild/EMULATOR/EMULATOR_TIMER.H
Normal file
24
src_rebuild/EMULATOR/EMULATOR_TIMER.H
Normal 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
|
@ -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)
|
||||
{
|
||||
|
@ -7,17 +7,21 @@
|
||||
SDL_GameController* padHandle[MAX_CONTROLLERS];
|
||||
unsigned char* padData[MAX_CONTROLLERS];
|
||||
|
||||
const unsigned char* keyboardState;
|
||||
const unsigned char* keyboardState = NULL;
|
||||
|
||||
|
||||
void PadInitDirect(unsigned char* pad1, unsigned char* pad2)
|
||||
{
|
||||
// do not init second time!
|
||||
if (keyboardState != NULL)
|
||||
return;
|
||||
|
||||
if (pad1 != NULL)
|
||||
{
|
||||
padData[0] = pad1;
|
||||
|
||||
PADRAW* pad = (PADRAW*)pad1;
|
||||
pad->id = 0x41; // always init first controller
|
||||
pad->id = 0;
|
||||
pad->analog[0] = 128;
|
||||
pad->analog[1] = 128;
|
||||
pad->analog[2] = 128;
|
||||
@ -361,10 +365,10 @@ void InternalPadUpdates()
|
||||
pad->status = 0; // PadStateStable?
|
||||
|
||||
// switch to analog state
|
||||
if(pad->analog[0] != 127 ||
|
||||
pad->analog[1] != 127 ||
|
||||
pad->analog[2] != 127 ||
|
||||
pad->analog[3] != 127 ||
|
||||
if((pad->analog[0] == 255 ||
|
||||
pad->analog[1] == 255 ||
|
||||
pad->analog[2] == 255 ||
|
||||
pad->analog[3] == 255) &&
|
||||
pad->id == 0x41)
|
||||
{
|
||||
eprintf("Switched controller type to ANALOG\n");
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1229,14 +1229,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 +1273,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 +1294,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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -3260,6 +3260,7 @@ int PingInCivCar(int minPingInDist)
|
||||
int i;
|
||||
int oldCookieCount;
|
||||
uint retDistSq;
|
||||
unsigned char* slot;
|
||||
|
||||
//straight = NULL;
|
||||
//curve = NULL;
|
||||
@ -3286,12 +3287,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;
|
||||
@ -3317,6 +3318,27 @@ int PingInCivCar(int minPingInDist)
|
||||
|
||||
newCar = NULL;
|
||||
|
||||
// find a free slot
|
||||
carCnt = car_data;
|
||||
slot = reservedSlots;
|
||||
|
||||
do {
|
||||
if (carCnt->controlType == CONTROL_TYPE_NONE && *slot == 0)
|
||||
{
|
||||
newCar = carCnt;
|
||||
break;
|
||||
}
|
||||
|
||||
carCnt++;
|
||||
slot++;
|
||||
} while (carCnt < &car_data[MAX_TRAFFIC_CARS]);
|
||||
|
||||
if (newCar == NULL)
|
||||
{
|
||||
PingOutCivsOnly = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClearMem((char*)&civDat, sizeof(civDat));
|
||||
|
||||
baseLoc.vx = player[playerNum].spoolXZ->vx;
|
||||
@ -3334,8 +3356,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,34 +3391,12 @@ 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;
|
||||
|
||||
// find a free slot
|
||||
carCnt = car_data;
|
||||
slot = reservedSlots;
|
||||
|
||||
do {
|
||||
if (carCnt->controlType == CONTROL_TYPE_NONE && *slot == 0)
|
||||
{
|
||||
newCar = carCnt;
|
||||
break;
|
||||
}
|
||||
|
||||
carCnt++;
|
||||
slot++;
|
||||
} while (carCnt < &car_data[MAX_TRAFFIC_CARS]);
|
||||
|
||||
if (newCar == NULL)
|
||||
{
|
||||
PingOutCivsOnly = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
oldCookieCount = cookieCount;
|
||||
|
||||
do {
|
||||
@ -3406,7 +3406,9 @@ int PingInCivCar(int minPingInDist)
|
||||
cookieCount = 0;
|
||||
|
||||
if (cookieCount == oldCookieCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (requestCopCar == 0)
|
||||
{
|
||||
@ -3438,9 +3440,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
|
||||
{
|
||||
@ -3779,7 +3781,7 @@ int PingInCivCar(int minPingInDist)
|
||||
PingOutCivsOnly = 0;
|
||||
|
||||
// [A] REDRIVER2 always stores pings
|
||||
StorePingInfo(cookieCount, newCar->id);
|
||||
StorePingInfo(cookieCount, newCar->id); // + 1 since car with id 1 is not getting pinged in chases
|
||||
|
||||
return newCar->id + 1;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -1281,7 +1346,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 +1454,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 +1462,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 +1487,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
|
||||
|
@ -1,6 +1,16 @@
|
||||
#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 gSkipInGameCutscene;
|
||||
|
@ -3009,6 +3009,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)
|
||||
{
|
||||
|
@ -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++)
|
||||
|
@ -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);
|
||||
|
@ -16,5 +16,6 @@ extern void SetPleaseWait(char *buffer); // 0x000448CC
|
||||
|
||||
extern void CheckForCorrectDisc(int disc); // 0x00044A40
|
||||
|
||||
extern void ShowBonusGallery();
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
@ -633,7 +633,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 +645,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 +3630,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 +3676,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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -2374,7 +2374,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 +2616,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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -3354,6 +3354,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);
|
||||
}
|
||||
|
@ -49,6 +49,22 @@ unsigned short *Low2LowerDetailTable = NULL;
|
||||
/* end block 3 */
|
||||
// End Line: 79
|
||||
|
||||
// [A]
|
||||
void CleanSpooledModelSlots()
|
||||
{
|
||||
int i;
|
||||
|
||||
// assign model pointers
|
||||
for (i = 0; i < MAX_MODEL_SLOTS; i++) // [A] bug fix. Init with dummyModel
|
||||
{
|
||||
if(!(modelpointers[i]->shape_flags & 0x8000))
|
||||
{
|
||||
modelpointers[i] = &dummyModel;
|
||||
pLodModels[i] = &dummyModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [D] [T]
|
||||
void ProcessMDSLump(char *lump_file, int lump_size)
|
||||
{
|
||||
@ -74,8 +90,13 @@ void ProcessMDSLump(char *lump_file, int lump_size)
|
||||
size = *(int*)mdsfile;
|
||||
mdsfile += sizeof(int);
|
||||
|
||||
if (size)
|
||||
modelpointers[i] = (MODEL*)mdsfile;
|
||||
if (size)
|
||||
{
|
||||
model = (MODEL*)mdsfile;
|
||||
model->shape_flags |= 0x8000; // [A] non-spooled flag
|
||||
|
||||
modelpointers[i] = model;
|
||||
}
|
||||
|
||||
mdsfile += size;
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ extern unsigned short *Low2LowerDetailTable;
|
||||
|
||||
extern int num_models_in_pack;
|
||||
|
||||
void CleanSpooledModelSlots();
|
||||
|
||||
extern void ProcessMDSLump(char *lump_file, int lump_size); // 0x00064CFC
|
||||
|
||||
extern int ProcessCarModelLump(char *lump_ptr, int lump_size); // 0x00064E6C
|
||||
|
@ -18,21 +18,23 @@
|
||||
|
||||
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:
|
||||
@ -58,50 +60,53 @@ PERCENTAGE_BAR ProxyBar;
|
||||
|
||||
int gDoOverlays = 1;
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void InitOverlays(void)
|
||||
{
|
||||
bool bVar1;
|
||||
gDoOverlays = 1;
|
||||
|
||||
InitPercentageBar(&PlayerDamageBar, MaxPlayerDamage[0], playerDamageColour, "Damage");
|
||||
|
||||
PlayerDamageBar.xpos = 0x10;
|
||||
PlayerDamageBar.ypos = 0x18;
|
||||
PlayerDamageBar.xpos = 16;
|
||||
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 = 16;
|
||||
Player2DamageBar.ypos = 140;
|
||||
Player2DamageBar.active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Player2DamageBar.active = 0;
|
||||
}
|
||||
|
||||
Player2DamageBar.active = (bVar1);
|
||||
|
||||
InitPercentageBar(&FelonyBar, 0x1000, felonyColour, "Felony");
|
||||
FelonyBar.xpos = 0x10;
|
||||
FelonyBar.ypos = 0x2e;
|
||||
FelonyBar.xpos = 16;
|
||||
FelonyBar.ypos = 46;
|
||||
FelonyBar.active = 0;
|
||||
|
||||
InitPercentageBar(&DamageBar, 1, damageColour, "Damage");
|
||||
DamageBar.xpos = 0xd0;
|
||||
DamageBar.ypos = 0x18;
|
||||
DamageBar.xpos = 208;
|
||||
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 = 16;
|
||||
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 +129,55 @@ 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;
|
||||
|
||||
DrawPercentageBar(&PlayerDamageBar);
|
||||
DrawPercentageBar(&Player2DamageBar);
|
||||
DrawPercentageBar(&DamageBar);
|
||||
DrawPercentageBar(&FelonyBar);
|
||||
|
||||
DrawDrivingGameOverlays();
|
||||
DrawOverheadMap();
|
||||
|
||||
if (CopsCanSeePlayer)
|
||||
{
|
||||
if (CurrentPlayerView == 0)
|
||||
return;
|
||||
if (player[0].playerCarId < 0)
|
||||
felony = &pedestrianFelony;
|
||||
else
|
||||
felony = &car_data[player[0].playerCarId].felonyRating;
|
||||
|
||||
SetFullscreenDrawing();
|
||||
}
|
||||
|
||||
UpdateFlashValue();
|
||||
|
||||
if (gShowMap == 0)
|
||||
{
|
||||
FastForward = 0;
|
||||
|
||||
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 +218,7 @@ void DisplayOverlays(void)
|
||||
|
||||
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void SetFullscreenDrawing(void)
|
||||
{
|
||||
DR_ENV *drenv;
|
||||
@ -222,7 +227,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 +256,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->width = 102;
|
||||
bar->height = 10;
|
||||
bar->position = 0;
|
||||
bar->max = (ushort)size;
|
||||
bar->max = size;
|
||||
bar->pColourBand = pColourBand;
|
||||
bar->flags = 0;
|
||||
bar->tag = tag;
|
||||
@ -287,11 +292,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 +336,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 +357,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 +438,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 +476,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 +539,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 +575,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 +598,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 +626,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 +644,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 +665,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 +716,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 +776,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 +824,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 +905,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 +919,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 +1082,7 @@ void DrawDrivingGameOverlays(void)
|
||||
/* end block 3 */
|
||||
// End Line: 2407
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void PrintScoreTableTime(int x, int y, int time)
|
||||
{
|
||||
char string[32];
|
||||
|
@ -136,67 +136,53 @@ static int gUseRotatedMap = 0;
|
||||
|
||||
/* WARNING: Could not reconcile some variable overlaps */
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void DrawTargetBlip(VECTOR *pos, unsigned char r, unsigned char g, unsigned char b, ulong flags)
|
||||
{
|
||||
int ysize;
|
||||
POLY_FT4 *poly;
|
||||
VECTOR vec;
|
||||
|
||||
if ((flags & 0x20) == 0)
|
||||
{
|
||||
if ((flags & 8) == 0)
|
||||
{
|
||||
if ((flags & 1) == 0)
|
||||
{
|
||||
WorldToFullscreenMap2(pos, &vec);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldToOverheadMapPositions(pos, &vec, 1, 0, 0);
|
||||
if (0x5e < vec.vx - 0xe9U)
|
||||
return;
|
||||
|
||||
if (vec.vz < 0xae)
|
||||
return;
|
||||
|
||||
if (0xfa < vec.vz)
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
vec.vx = pos->vx;
|
||||
vec.vy = pos->vy;
|
||||
vec.vz = pos->vz;
|
||||
vec.pad = pos->pad;
|
||||
}
|
||||
if ((flags & 1) == 0) {
|
||||
vec.vx = vec.vx + map_x_offset;
|
||||
vec.vz = vec.vz + map_z_offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (flags & 0x20)
|
||||
{
|
||||
WorldToMultiplayerMap(pos, &vec);
|
||||
|
||||
vec.vx += 240;
|
||||
vec.vz += 96;
|
||||
}
|
||||
|
||||
if ((flags & 0x10) == 0)
|
||||
else if (flags & 0x8)
|
||||
{
|
||||
ysize = 4;
|
||||
vec.vx = pos->vx;
|
||||
vec.vz = pos->vz;
|
||||
}
|
||||
else if (flags & 0x1)
|
||||
{
|
||||
WorldToOverheadMapPositions(pos, &vec, 1, 0, 0);
|
||||
|
||||
if ((flags & 2) != 0)
|
||||
{
|
||||
ysize = 3;
|
||||
}
|
||||
if (vec.vx - 233U > 94)
|
||||
return;
|
||||
|
||||
if (vec.vz < 174 || vec.vz > 250)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ysize = OverlayFlashValue >> 1;
|
||||
WorldToFullscreenMap2(pos, &vec);
|
||||
}
|
||||
|
||||
if ((flags & 1) == 0)
|
||||
{
|
||||
vec.vx += map_x_offset;
|
||||
vec.vz += map_z_offset;
|
||||
}
|
||||
|
||||
if (flags & 0x10)
|
||||
ysize = OverlayFlashValue / 2;
|
||||
else if (flags & 0x2)
|
||||
ysize = 3;
|
||||
else
|
||||
ysize = 4;
|
||||
|
||||
poly = (POLY_FT4 *)current->primptr;
|
||||
|
||||
setPolyFT4(poly);
|
||||
@ -204,10 +190,13 @@ void DrawTargetBlip(VECTOR *pos, unsigned char r, unsigned char g, unsigned char
|
||||
|
||||
poly->x0 = vec.vx - ysize;
|
||||
poly->y0 = vec.vz - ysize;
|
||||
|
||||
poly->x1 = vec.vx + ysize;
|
||||
poly->y1 = vec.vz - ysize;
|
||||
|
||||
poly->x2 = vec.vx - ysize;
|
||||
poly->y2 = vec.vz + ysize;
|
||||
|
||||
poly->x3 = vec.vx + ysize;
|
||||
poly->y3 = vec.vz + ysize;
|
||||
|
||||
@ -215,30 +204,27 @@ void DrawTargetBlip(VECTOR *pos, unsigned char r, unsigned char g, unsigned char
|
||||
poly->g0 = g;
|
||||
poly->b0 = b;
|
||||
|
||||
poly->u0 = light_texture.coords.u0;
|
||||
poly->v0 = light_texture.coords.v0;
|
||||
poly->u1 = light_texture.coords.u1;
|
||||
poly->v1 = light_texture.coords.v1;
|
||||
poly->u2 = light_texture.coords.u2;
|
||||
poly->v2 = light_texture.coords.v2;
|
||||
poly->u3 = light_texture.coords.u3;
|
||||
poly->v3 = light_texture.coords.v3;
|
||||
*(ushort*)&poly->u0 = *(ushort*)&light_texture.coords.u0;
|
||||
*(ushort*)&poly->u1 = *(ushort*)&light_texture.coords.u1;
|
||||
*(ushort*)&poly->u2 = *(ushort*)&light_texture.coords.u2;
|
||||
*(ushort*)&poly->u3 = *(ushort*)&light_texture.coords.u3;
|
||||
|
||||
if ((flags & 2) == 0)
|
||||
poly->tpage = light_texture.tpageid | 0x20;
|
||||
else
|
||||
if (flags & 0x2)
|
||||
poly->tpage = light_texture.tpageid | 0x40;
|
||||
else
|
||||
poly->tpage = light_texture.tpageid | 0x20;
|
||||
|
||||
poly->clut = light_texture.clutid;
|
||||
|
||||
if ((flags & 4) == 0)
|
||||
if (flags & 0x4)
|
||||
{
|
||||
addPrim(current->ot, poly);
|
||||
current->primptr += sizeof(POLY_FT4);
|
||||
// fullscreen map mode
|
||||
DrawPrim(poly);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawPrim(poly);
|
||||
addPrim(current->ot, poly);
|
||||
current->primptr += sizeof(POLY_FT4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,74 +255,65 @@ void DrawTargetBlip(VECTOR *pos, unsigned char r, unsigned char g, unsigned char
|
||||
|
||||
/* WARNING: Could not reconcile some variable overlaps */
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void DrawTargetArrow(VECTOR *pos, ulong flags)
|
||||
{
|
||||
short sVar1;
|
||||
short sVar2;
|
||||
int y;
|
||||
int x;
|
||||
int dy;
|
||||
int dx;
|
||||
POLY_G3 *poly;
|
||||
VECTOR vec;
|
||||
VECTOR vec2;
|
||||
|
||||
if ((flags & 8) == 0)
|
||||
{
|
||||
if ((flags & 1) == 0)
|
||||
{
|
||||
WorldToFullscreenMap2(pos, &vec);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldToOverheadMapPositions(pos, &vec, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (flags & 0x8)
|
||||
{
|
||||
vec.vx = pos->vx;
|
||||
vec.vy = pos->vy;
|
||||
vec.vz = pos->vz;
|
||||
vec.pad = pos->pad;
|
||||
}
|
||||
|
||||
if ((flags & 1) == 0)
|
||||
else if (flags & 0x1)
|
||||
{
|
||||
vec.vx = vec.vx + map_x_offset;
|
||||
vec.vz = vec.vz + map_z_offset;
|
||||
vec2.vx = map_x_offset + 0xa0;
|
||||
vec2.vz = map_z_offset + 0x80;
|
||||
WorldToOverheadMapPositions(pos, &vec, 1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldToFullscreenMap2(pos, &vec);
|
||||
}
|
||||
|
||||
if (flags & 0x1)
|
||||
{
|
||||
WorldToOverheadMapPositions((VECTOR *)player, &vec2, 1, '\0', 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec.vx = vec.vx + map_x_offset;
|
||||
vec.vz = vec.vz + map_z_offset;
|
||||
|
||||
x = vec2.vx - vec.vx;
|
||||
y = vec2.vz - vec.vz;
|
||||
vec2.vx = map_x_offset + 160;
|
||||
vec2.vz = map_z_offset + 128;
|
||||
}
|
||||
|
||||
// target arrow perpendicular
|
||||
dx = (vec2.vx - vec.vx) / 8;
|
||||
dy = (vec2.vz - vec.vz) / 8;
|
||||
|
||||
poly = (POLY_G3 *)current->primptr;
|
||||
|
||||
setPolyG3(poly);
|
||||
setSemiTrans(poly, 1);
|
||||
|
||||
poly->r0 = 24;
|
||||
poly->g0 = 24;
|
||||
poly->b0 = 24;
|
||||
poly->r1 = 24;
|
||||
poly->g1 = 24;
|
||||
poly->b1 = 24;
|
||||
poly->r0 = poly->r1 = 24;
|
||||
poly->g0 = poly->g1 = 24;
|
||||
poly->b0 = poly->b1 = 24;
|
||||
|
||||
poly->r2 = 64;
|
||||
poly->g2 = 64;
|
||||
poly->b2 = 64;
|
||||
|
||||
sVar1 = (y >> 3);
|
||||
sVar2 = (x >> 3);
|
||||
poly->x0 = vec2.vx + dy;
|
||||
poly->y0 = vec2.vz - dx;
|
||||
|
||||
poly->x1 = vec2.vx - dy;
|
||||
poly->y1 = vec2.vz + dx;
|
||||
|
||||
poly->x0 = vec2.vx + sVar1;
|
||||
poly->y0 = vec2.vz - sVar2;
|
||||
poly->x1 = vec2.vx - sVar1;
|
||||
poly->y1 = vec2.vz + sVar2;
|
||||
poly->x2 = vec.vx;
|
||||
poly->y2 = vec.vz;
|
||||
|
||||
@ -354,16 +331,18 @@ void DrawTargetArrow(VECTOR *pos, ulong flags)
|
||||
|
||||
null->tpage = 0x40;
|
||||
|
||||
if ((flags & 4) == 0)
|
||||
if (flags & 0x4)
|
||||
{
|
||||
addPrim(current->ot, poly);
|
||||
addPrim(current->ot, null);
|
||||
current->primptr += sizeof(POLY_G3) + sizeof(POLY_FT3);
|
||||
// fullscreen map
|
||||
DrawPrim(null);
|
||||
DrawPrim(poly);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawPrim(null);
|
||||
DrawPrim(poly);
|
||||
addPrim(current->ot, poly);
|
||||
addPrim(current->ot, null);
|
||||
|
||||
current->primptr += sizeof(POLY_G3) + sizeof(POLY_FT3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,74 +376,65 @@ void DrawTargetArrow(VECTOR *pos, ulong flags)
|
||||
/* end block 3 */
|
||||
// End Line: 1822
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void DrawPlayerDot(VECTOR *pos, short rot, unsigned char r, unsigned char g, int b, ulong flags)
|
||||
{
|
||||
int iVar2;
|
||||
int iVar3;
|
||||
int sn;
|
||||
int cs;
|
||||
POLY_F3 *poly;
|
||||
VECTOR direction;
|
||||
SVECTOR apos[3];
|
||||
VECTOR opos[3];
|
||||
VECTOR vec;
|
||||
|
||||
if ((flags & 0x20) == 0)
|
||||
{
|
||||
if ((flags & 8) == 0)
|
||||
{
|
||||
if ((flags & 1) == 0)
|
||||
{
|
||||
WorldToFullscreenMap2(pos, &vec);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldToOverheadMapPositions(pos, &vec, 1, 0, 0);
|
||||
if (0x5e < vec.vx - 0xe9U)
|
||||
return;
|
||||
|
||||
if (vec.vz < 0xae)
|
||||
return;
|
||||
|
||||
if (0xfa < vec.vz)
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vec.vx = pos->vx;
|
||||
vec.vy = pos->vy;
|
||||
vec.vz = pos->vz;
|
||||
vec.pad = pos->pad;
|
||||
}
|
||||
|
||||
if ((flags & 1) == 0)
|
||||
{
|
||||
vec.vx = vec.vx + map_x_offset;
|
||||
vec.vz = vec.vz + map_z_offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (flags & 0x20)
|
||||
{
|
||||
WorldToMultiplayerMap(pos, &vec);
|
||||
|
||||
vec.vx += 240;
|
||||
vec.vz += 96;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & 0x8)
|
||||
{
|
||||
vec.vx = pos->vx;
|
||||
vec.vz = pos->vz;
|
||||
}
|
||||
else if (flags & 0x1)
|
||||
{
|
||||
WorldToOverheadMapPositions(pos, &vec, 1, 0, 0);
|
||||
|
||||
if (vec.vx - 233U > 94)
|
||||
return;
|
||||
|
||||
iVar2 = rcossin_tbl[(rot & 0xfffU) * 2];
|
||||
iVar3 = rcossin_tbl[(rot & 0xfffU) * 2 + 1];
|
||||
if (vec.vz < 174 || vec.vz > 250)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldToFullscreenMap2(pos, &vec);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & 0x1) == 0)
|
||||
{
|
||||
vec.vx += map_x_offset;
|
||||
vec.vz += map_z_offset;
|
||||
}
|
||||
|
||||
sn = rcossin_tbl[(rot & 0xfffU) * 2];
|
||||
cs = rcossin_tbl[(rot & 0xfffU) * 2 + 1];
|
||||
|
||||
opos[2].vx = vec.vx;
|
||||
opos[2].vz = vec.vz;
|
||||
|
||||
opos[0].vx = opos[2].vx + (iVar2 * -3 + 0x800 >> 0xc);
|
||||
opos[0].vz = opos[2].vz + FIXEDH(iVar3 * -3);
|
||||
opos[0].vx = vec.vx + FIXEDH(sn * -3);
|
||||
opos[0].vz = vec.vz + FIXEDH(cs * -3);
|
||||
|
||||
opos[1].vx = opos[2].vx + FIXEDH(iVar2 * 3 + iVar3 * -2);
|
||||
opos[1].vz = opos[2].vz + FIXEDH(iVar3 * 3 + iVar2 * 2);
|
||||
opos[1].vx = vec.vx + FIXEDH(sn * 3 + cs * -2);
|
||||
opos[1].vz = vec.vz + FIXEDH(cs * 3 + sn * 2);
|
||||
|
||||
opos[2].vx = opos[2].vx + FIXEDH(iVar3 * 2 + iVar2 * 3);
|
||||
opos[2].vz = opos[2].vz + FIXEDH(iVar2 * -2 + iVar3 * 3);
|
||||
opos[2].vx = vec.vx + FIXEDH(cs * 2 + sn * 3);
|
||||
opos[2].vz = vec.vz + FIXEDH(sn * -2 + cs * 3);
|
||||
|
||||
poly = (POLY_F3 *)current->primptr;
|
||||
setPolyF3(poly);
|
||||
@ -475,19 +445,21 @@ void DrawPlayerDot(VECTOR *pos, short rot, unsigned char r, unsigned char g, int
|
||||
|
||||
poly->x0 = opos[0].vx;
|
||||
poly->y0 = opos[0].vz;
|
||||
|
||||
poly->x1 = opos[1].vx;
|
||||
poly->y1 = opos[1].vz;
|
||||
|
||||
poly->x2 = opos[2].vx;
|
||||
poly->y2 = opos[2].vz;
|
||||
|
||||
if ((flags & 4) == 0)
|
||||
if (flags & 0x4)
|
||||
{
|
||||
addPrim(current->ot, poly);
|
||||
current->primptr += sizeof(POLY_F3);
|
||||
DrawPrim(poly);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawPrim(poly);
|
||||
addPrim(current->ot, poly);
|
||||
current->primptr += sizeof(POLY_F3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -514,7 +486,7 @@ void DrawPlayerDot(VECTOR *pos, short rot, unsigned char r, unsigned char g, int
|
||||
/* end block 2 */
|
||||
// End Line: 1983
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void ProcessOverlayLump(char *lump_ptr, int lump_size)
|
||||
{
|
||||
int i;
|
||||
@ -525,15 +497,15 @@ void ProcessOverlayLump(char *lump_ptr, int lump_size)
|
||||
MapTPage = info.tpageid;
|
||||
MapClut = GetClut(mapclutpos.x, mapclutpos.y);
|
||||
|
||||
MapRect.w = 0x40;
|
||||
MapRect.h = 0x100;
|
||||
MapRect.x = (MapTPage & 0xf) << 6;
|
||||
MapRect.y = (MapTPage & 0x10) << 4;
|
||||
MapRect.w = 64;
|
||||
MapRect.h = 256;
|
||||
MapRect.x = (MapTPage & 15) << 6;
|
||||
MapRect.y = (MapTPage & 16) << 4;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
MapSegmentPos[i].x = (((i & 3) * 32 + info.coords.u0) >> 2);
|
||||
MapSegmentPos[i].y = info.coords.v0 + (i >> 2) * 32;
|
||||
MapSegmentPos[i].x = ((i & 3) * 32 + info.coords.u0) / 4;
|
||||
MapSegmentPos[i].y = info.coords.v0 + (i / 4) * 32;
|
||||
|
||||
i++;
|
||||
} while (i < 16);
|
||||
@ -545,7 +517,7 @@ void ProcessOverlayLump(char *lump_ptr, int lump_size)
|
||||
|
||||
MALLOC_END();
|
||||
|
||||
LoadImage(&mapclutpos, (u_long *)(MapBitMaps + 0x200));
|
||||
LoadImage(&mapclutpos, (u_long *)(MapBitMaps + 512));
|
||||
DrawSync(0);
|
||||
}
|
||||
|
||||
@ -603,45 +575,36 @@ void ProcessOverlayLump(char *lump_ptr, int lump_size)
|
||||
/* end block 3 */
|
||||
// End Line: 2100
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
ulong Long2DDistance(VECTOR *pPoint1, VECTOR *pPoint2)
|
||||
{
|
||||
short sVar1;
|
||||
int iVar2;
|
||||
uint uVar3;
|
||||
long y;
|
||||
int x;
|
||||
ulong uVar4;
|
||||
int tempTheta;
|
||||
int theta;
|
||||
ulong result;
|
||||
VECTOR delta;
|
||||
|
||||
x = pPoint1->vx - pPoint2->vx;
|
||||
delta.vx = ABS(pPoint1->vx - pPoint2->vx);
|
||||
delta.vz = ABS(pPoint1->vz - pPoint2->vz);
|
||||
|
||||
if (x < 0)
|
||||
x = pPoint2->vx - pPoint1->vx;
|
||||
theta = ratan2(delta.vz, delta.vx);
|
||||
|
||||
y = pPoint1->vz - pPoint2->vz;
|
||||
|
||||
if (y < 0)
|
||||
y = pPoint2->vz - pPoint1->vz;
|
||||
|
||||
uVar3 = ratan2(y, x);
|
||||
if ((uVar3 & 0x7ff) - 0x200 < 0x401)
|
||||
if ((theta & 0x7ff) - 512U <= 1024)
|
||||
{
|
||||
sVar1 = rcossin_tbl[(uVar3 & 0xfff) * 2];
|
||||
x = y;
|
||||
tempTheta = rcossin_tbl[(theta & 0xfff) * 2];
|
||||
result = delta.vz;
|
||||
}
|
||||
else
|
||||
{
|
||||
sVar1 = rcossin_tbl[(uVar3 & 0xfff) * 2 + 1];
|
||||
tempTheta = rcossin_tbl[(theta & 0xfff) * 2 + 1];
|
||||
result = delta.vx;
|
||||
}
|
||||
|
||||
iVar2 = sVar1;
|
||||
|
||||
if (x < 0x80000)
|
||||
uVar4 = (x << 0xc) / iVar2;
|
||||
if (result < 0x80000)
|
||||
result = (result << 12) / tempTheta;
|
||||
else
|
||||
uVar4 = (x << 9) / iVar2 << 3;
|
||||
result = (result << 9) / tempTheta << 3;
|
||||
|
||||
return uVar4;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -678,42 +641,37 @@ ulong Long2DDistance(VECTOR *pPoint1, VECTOR *pPoint2)
|
||||
|
||||
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
||||
|
||||
// [D]
|
||||
// [D] [T]
|
||||
void InitOverheadMap(void)
|
||||
{
|
||||
int d;
|
||||
int c;
|
||||
int tpage;
|
||||
|
||||
if (gMultiplayerLevels == 0)
|
||||
{
|
||||
SetMapPos();
|
||||
tilehnum = overlaidmaps[GameLevel].width / 32;
|
||||
|
||||
c = 0;
|
||||
tpage = 0;
|
||||
do {
|
||||
d = 0;
|
||||
|
||||
do {
|
||||
maptile[d][c] = tpage;
|
||||
|
||||
LoadMapTile(tpage, (x_map >> 5) + d, (y_map >> 5) + c);
|
||||
|
||||
d++;
|
||||
tpage++;
|
||||
} while (d < 4);
|
||||
|
||||
c++;
|
||||
} while (c < 4);
|
||||
|
||||
old_x_mod = x_map & 0x1f;
|
||||
old_y_mod = y_map & 0x1f;
|
||||
}
|
||||
else
|
||||
if (gMultiplayerLevels)
|
||||
{
|
||||
InitMultiplayerMap();
|
||||
return;
|
||||
}
|
||||
|
||||
SetMapPos();
|
||||
tilehnum = overlaidmaps[GameLevel].width / 32;
|
||||
|
||||
tpage = 0;
|
||||
|
||||
for (c = 0; c < 4; c++)
|
||||
{
|
||||
for (d = 0; d < 4; d++)
|
||||
{
|
||||
maptile[d][c] = tpage;
|
||||
|
||||
LoadMapTile(tpage, (x_map >> 5) + d, (y_map >> 5) + c);
|
||||
tpage++;
|
||||
}
|
||||
}
|
||||
|
||||
old_x_mod = x_map & 0x1f;
|
||||
old_y_mod = y_map & 0x1f;
|
||||
}
|
||||
|
||||
|
||||
@ -854,7 +812,7 @@ void DrawOverheadMap(void)
|
||||
short uVar7;
|
||||
short uVar8;
|
||||
unsigned char uVar10;
|
||||
short *psVar11;
|
||||
short *playerFelony;
|
||||
TILE_1 *tile1;
|
||||
POLY_F4 *polyf4;
|
||||
int x;
|
||||
@ -910,66 +868,57 @@ void DrawOverheadMap(void)
|
||||
|
||||
VECTOR translate = { 280, 0, 212 };
|
||||
|
||||
if (gMultiplayerLevels != 0)
|
||||
if (gMultiplayerLevels)
|
||||
{
|
||||
DrawMultiplayerMap();
|
||||
return;
|
||||
}
|
||||
if (1 < NumPlayers)
|
||||
|
||||
if (NumPlayers > 1)
|
||||
return;
|
||||
|
||||
SetMapPos();
|
||||
uVar28 = x_map & 0x1f;
|
||||
uVar30 = y_map & 0x1f;
|
||||
SetMapPos();
|
||||
draw_box();
|
||||
|
||||
if (0 < player_position_known)
|
||||
// flash the overhead map
|
||||
if (player_position_known > 0)
|
||||
{
|
||||
if (player[0].playerCarId < 0)
|
||||
psVar11 = &pedestrianFelony;
|
||||
playerFelony = &pedestrianFelony;
|
||||
else
|
||||
psVar11 = &car_data[player[0].playerCarId].felonyRating;
|
||||
playerFelony = &car_data[player[0].playerCarId].felonyRating;
|
||||
|
||||
if (*psVar11 > FELONY_MIN_VALUE)
|
||||
{
|
||||
if (*playerFelony > FELONY_MIN_VALUE)
|
||||
FlashOverheadMap(ptab[CameraCnt & 0xf], 0, ptab[CameraCnt + 8U & 0xf]);
|
||||
goto LAB_00016fac;
|
||||
}
|
||||
}
|
||||
|
||||
if (player_position_known == -1)
|
||||
{
|
||||
if (flashtimer == 0)
|
||||
{
|
||||
if (player[0].playerCarId < 0)
|
||||
psVar11 = &pedestrianFelony;
|
||||
else
|
||||
psVar11 = &car_data[player[0].playerCarId].felonyRating;
|
||||
|
||||
if (*psVar11 > FELONY_MIN_VALUE)
|
||||
flashtimer = 48;
|
||||
|
||||
goto LAB_00016ee8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LAB_00016ee8:
|
||||
if (flashtimer == 0)
|
||||
goto LAB_00016fac;
|
||||
if (player_position_known == -1)
|
||||
{
|
||||
if (flashtimer == 0)
|
||||
{
|
||||
if (player[0].playerCarId < 0)
|
||||
playerFelony = &pedestrianFelony;
|
||||
else
|
||||
playerFelony = &car_data[player[0].playerCarId].felonyRating;
|
||||
|
||||
if (*playerFelony > FELONY_MIN_VALUE)
|
||||
flashtimer = 48;
|
||||
}
|
||||
}
|
||||
|
||||
if (flashtimer)
|
||||
{
|
||||
flashtimer--;
|
||||
r = -flashtimer;
|
||||
|
||||
r = ptab2[r + 47 >> 2] + ptab2[r + 48 >> 2] + ptab2[r + 49 >> 2] + ptab2[r + 50 >> 2];
|
||||
r = r >> 2;
|
||||
|
||||
FlashOverheadMap(r, r, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
flashtimer--;
|
||||
r = -flashtimer;
|
||||
|
||||
r = ptab2[r + 47 >> 2] + ptab2[r + 48 >> 2] + ptab2[r + 49 >> 2] + ptab2[r + 50 >> 2];
|
||||
r = r >> 2;
|
||||
|
||||
FlashOverheadMap(r, r, r);
|
||||
|
||||
LAB_00016fac:
|
||||
|
||||
drarea = (DR_AREA *)current->primptr;
|
||||
SetDrawArea(drarea, ¤t->draw.clip);
|
||||
|
||||
@ -978,14 +927,14 @@ LAB_00016fac:
|
||||
|
||||
WorldToOverheadMapPositions((VECTOR *)player->pos, &vec, 1, 0, 0);
|
||||
|
||||
if (((vec.vx - 0xe9U < 0x5f) && (0xad < vec.vz)) && (vec.vz < 0xfb))
|
||||
if (vec.vx - 233U < 95 && vec.vz > 173 && vec.vz < 251)
|
||||
{
|
||||
tile1 = (TILE_1 *)current->primptr;
|
||||
setTile1(tile1);
|
||||
|
||||
tile1->r0 = -1;
|
||||
tile1->g0 = -1;
|
||||
tile1->b0 = -1;
|
||||
tile1->r0 = 255;
|
||||
tile1->g0 = 255;
|
||||
tile1->b0 = 255;
|
||||
|
||||
tile1->x0 = vec.vx;
|
||||
tile1->y0 = vec.vz;
|
||||
@ -998,17 +947,20 @@ LAB_00016fac:
|
||||
DrawCompass();
|
||||
DrawOverheadTargets();
|
||||
|
||||
sVar3 = -uVar30;
|
||||
|
||||
// draw cop sight
|
||||
cp = car_data;
|
||||
do {
|
||||
if (cp->controlType == CONTROL_TYPE_PURSUER_AI && cp->ai.p.dying == 0 || (cp->controlFlags & 1) != 0)
|
||||
if (cp->controlType == CONTROL_TYPE_PURSUER_AI && cp->ai.p.dying == 0 || (cp->controlFlags & CONTROL_FLAG_COP))
|
||||
DrawSightCone(&copSightData, (VECTOR *)cp->hd.where.t, cp->hd.direction);
|
||||
|
||||
cp++;
|
||||
} while (cp <= &car_data[MAX_CARS]);
|
||||
|
||||
uVar28 = x_map & 0x1f;
|
||||
uVar30 = y_map & 0x1f;
|
||||
|
||||
sVar2 = -uVar28;
|
||||
sVar3 = -uVar30;
|
||||
|
||||
// X axis
|
||||
if ((uVar28 < 16) && (old_x_mod > 16))
|
||||
@ -1024,7 +976,7 @@ LAB_00016fac:
|
||||
maptile[2][r] = maptile[3][r];
|
||||
maptile[3][r] = bVar1;
|
||||
|
||||
LoadMapTile(bVar1, x_map / 32 + 3, y_map / 32 + r);
|
||||
LoadMapTile(bVar1, (x_map >> 5) + 3, (y_map >> 5) + r);
|
||||
|
||||
r++;
|
||||
} while (r < 4);
|
||||
@ -1043,7 +995,7 @@ LAB_00016fac:
|
||||
maptile[1][r] = maptile[0][r];
|
||||
maptile[0][r] = bVar1;
|
||||
|
||||
LoadMapTile(bVar1, x_map / 32, y_map / 32 + r);
|
||||
LoadMapTile(bVar1, (x_map >> 5), (y_map >> 5) + r);
|
||||
r++;
|
||||
} while (r < 4);
|
||||
}
|
||||
@ -1061,7 +1013,7 @@ LAB_00016fac:
|
||||
maptile[r][2] = maptile[r][3];
|
||||
maptile[r][3] = bVar1;
|
||||
|
||||
LoadMapTile(bVar1, x_map / 32 + r, y_map / 32 + 3);
|
||||
LoadMapTile(bVar1, (x_map >> 5) + r, (y_map >> 5) + 3);
|
||||
r++;
|
||||
} while (r < 4);
|
||||
}
|
||||
@ -1078,7 +1030,7 @@ LAB_00016fac:
|
||||
maptile[r][1] = maptile[r][0];
|
||||
maptile[r][0] = bVar1;
|
||||
|
||||
LoadMapTile(bVar1, x_map / 32 + r, y_map / 32);
|
||||
LoadMapTile(bVar1, (x_map >> 5) + r, (y_map >> 5));
|
||||
r++;
|
||||
} while (r < 4);
|
||||
}
|
||||
@ -1202,7 +1154,7 @@ LAB_00016fac:
|
||||
pbVar25 = (char*)maptile + y;
|
||||
plVar18 = &((VECTOR*)MapMeshO)[5].vz + iVar27 * 4;
|
||||
plVar16 = &((VECTOR*)MapMeshO)[5].vz + y * 4;
|
||||
psVar11 = &MapTex[0].w;
|
||||
playerFelony = &MapTex[0].w;
|
||||
|
||||
while (y_00 < r)
|
||||
{
|
||||
@ -1258,7 +1210,7 @@ LAB_00016fac:
|
||||
local_a3_2816->u3 = MapTex[y_00].u + MapSegmentPos[*pbVar25].x * 4 + cVar22;
|
||||
local_a3_2816->v3 = MapTex[y].v + MapSegmentPos[*pbVar25].y + cVar20;
|
||||
|
||||
psVar11 = psVar11 + 4;
|
||||
playerFelony = playerFelony + 4;
|
||||
plVar16 = plVar16 + 0x14;
|
||||
plVar18 = plVar18 + 0x14;
|
||||
pbVar25 = pbVar25 + 4;
|
||||
|
@ -686,14 +686,45 @@ void DrawPauseMenus(void)
|
||||
|
||||
void SaveReplay(int direction)
|
||||
{
|
||||
char filename[64];
|
||||
#ifdef PSX
|
||||
CallMemoryCard(0x10, 1);
|
||||
#else
|
||||
int size = SaveReplayToBuffer(_other_buffer);
|
||||
|
||||
FILE* fp = fopen("chase.d2rp", "wb");
|
||||
|
||||
#ifdef CUTSCENE_RECORDER
|
||||
extern int gCutsceneAsReplay;
|
||||
if(gCutsceneAsReplay != 0)
|
||||
{
|
||||
FILE* temp;
|
||||
int cnt;
|
||||
cnt = 2;
|
||||
|
||||
while(cnt < 14)
|
||||
{
|
||||
sprintf(filename, "CUT%d_%d.D2RP", gCutsceneAsReplay, cnt);
|
||||
|
||||
temp = fopen(filename, "rb");
|
||||
if (temp)
|
||||
{
|
||||
fclose(temp);
|
||||
cnt++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(filename, "CHASE.D2RP", gCurrentMissionNumber);
|
||||
}
|
||||
#else
|
||||
sprintf(filename, "CHASE.D2RP", gCurrentMissionNumber);
|
||||
#endif
|
||||
FILE* fp = fopen(filename, "wb");
|
||||
if (fp)
|
||||
{
|
||||
printInfo("Saving replay '%s'\n", filename);
|
||||
fwrite(_other_buffer, 1, size, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
@ -378,17 +379,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;
|
||||
}
|
||||
|
||||
@ -586,7 +587,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 +635,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 +713,10 @@ char GetPingInfo(char *cookieCount)
|
||||
|
||||
PingBufferPos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printInfo("-1 frame!\n");
|
||||
}
|
||||
|
||||
return retCarId;
|
||||
}
|
||||
@ -694,7 +736,12 @@ int StorePingInfo(int cookieCount, int carId)
|
||||
{
|
||||
packet = &PingBuffer[PingBufferPos++];
|
||||
packet->frame = (CameraCnt - frameStart & 0xffffU);
|
||||
packet->carId = carId;
|
||||
|
||||
if(carId == 1)
|
||||
packet->carId = MAX_CARS-1;
|
||||
else
|
||||
packet->carId = carId;
|
||||
|
||||
packet->cookieCount = cookieCount;
|
||||
|
||||
return 1;
|
||||
|
@ -110,7 +110,7 @@ int chunk_complete;
|
||||
|
||||
int new_area_location;
|
||||
int LoadingArea = 0;
|
||||
unsigned short *newmodels;
|
||||
unsigned short *newmodels = NULL;
|
||||
|
||||
SPOOLQ spooldata[48];
|
||||
|
||||
@ -1168,6 +1168,8 @@ void InitSpooling(void)
|
||||
ClearRegion(i);
|
||||
}
|
||||
|
||||
CleanSpooledModelSlots();
|
||||
|
||||
newmodels = NULL;
|
||||
spool_regioncounter = 0;
|
||||
spoolerror = 0;
|
||||
@ -1727,17 +1729,30 @@ void SetupModels(void)
|
||||
// [D] [T]
|
||||
void LoadInAreaModels(int area)
|
||||
{
|
||||
if (newmodels)
|
||||
int i;
|
||||
MODEL* model;
|
||||
int nmodels;
|
||||
unsigned short* new_model_numbers;
|
||||
int model_number;
|
||||
|
||||
if(newmodels)
|
||||
{
|
||||
// clear old model ids
|
||||
int nmodels = *newmodels;
|
||||
unsigned short* new_model_numbers = newmodels + 1;
|
||||
nmodels = *newmodels;
|
||||
new_model_numbers = newmodels + 1;
|
||||
|
||||
// set old model ids to dummy
|
||||
for (int i = 0; i < nmodels; i++)
|
||||
for (i = 0; i < nmodels; i++)
|
||||
{
|
||||
int model_number = new_model_numbers[i];
|
||||
modelpointers[model_number] = &dummyModel;
|
||||
model_number = new_model_numbers[i];
|
||||
|
||||
model = modelpointers[model_number];
|
||||
|
||||
if(model->shape_flags & 0x8000)
|
||||
{
|
||||
modelpointers[model_number] = &dummyModel;
|
||||
pLodModels[model_number] = &dummyModel;
|
||||
}
|
||||
}
|
||||
|
||||
SPOOL_INFO("freed %d model slots\n", nmodels);
|
||||
|
@ -1003,7 +1003,8 @@ void SwapDrawBuffers2(int player)
|
||||
|
||||
DrawSync(0);
|
||||
|
||||
if (player == 0) {
|
||||
if (player == 0)
|
||||
{
|
||||
PutDispEnv(¤t->disp);
|
||||
}
|
||||
|
||||
@ -1265,6 +1266,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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "SYSTEM.H"
|
||||
|
||||
#ifndef PSX
|
||||
#include "STRINGS.H"
|
||||
|
||||
#include "../utils/riff.h"
|
||||
#include "../utils/audio_source/snd_al_source.h"
|
||||
@ -49,6 +50,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 +74,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)
|
||||
{
|
||||
@ -347,6 +358,48 @@ void PlayXA(int num, int index)
|
||||
|
||||
if (g_wavData->Load(fileName))
|
||||
{
|
||||
#if 0
|
||||
// Save subtitles file
|
||||
{
|
||||
sprintf(fileName, "%sXA\\XABNK0%d.XA[%d].SBN", gDataFolder, num + 1, index);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
@ -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] = {
|
||||
@ -337,7 +338,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 +413,12 @@ void SetVariable(int var)
|
||||
GameType = GAME_IDLEDEMO;
|
||||
gCurrentMissionNumber = (value + 400);
|
||||
break;
|
||||
case 14: // [A]
|
||||
{
|
||||
ShowBonusGallery();
|
||||
|
||||
LoadFrontendScreens();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1041,25 +1048,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;
|
||||
|
||||
@ -1417,12 +1429,10 @@ int HandleKeyPress(void)
|
||||
{
|
||||
if (ScreenDepth > 0)
|
||||
{
|
||||
if (!bDoneAllready) {
|
||||
if (!bDoneAllready)
|
||||
FESound(0);
|
||||
}
|
||||
else {
|
||||
else
|
||||
bDoneAllready = 0;
|
||||
}
|
||||
|
||||
if (--ScreenDepth == 0)
|
||||
{
|
||||
@ -3485,6 +3495,7 @@ int CutSceneCitySelectScreen(int bSetup)
|
||||
LoadImage(&rect, (u_long *)_frontend_buffer);
|
||||
|
||||
DrawSync(0);
|
||||
|
||||
#ifdef PSX
|
||||
DisplayOnScreenText();
|
||||
|
||||
@ -4284,11 +4295,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 +4450,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:
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
#define GAME_VERSION_N "3.4 alpha"
|
||||
#define GAME_VERSION_N "4.2 alpha"
|
||||
#define GAME_TITLE "REDRIVER2"
|
||||
#define GAME_VERSION GAME_TITLE " " GAME_VERSION_N
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <SDL_scancode.h>
|
||||
|
||||
#include "C/CUTSCENE.H"
|
||||
|
||||
|
||||
// eq engine console output
|
||||
@ -355,7 +356,7 @@ void GameDebugKeys(int nKey, bool down)
|
||||
|
||||
#ifndef USE_CRT_MALLOC
|
||||
char g_Overlay_buffer[0x50000]; // 0x1C0000
|
||||
char g_Frontend_buffer[0x50000]; // 0xFB400
|
||||
char g_Frontend_buffer[0x60000]; // 0xFB400
|
||||
char g_Other_buffer[0x50000]; // 0xF3000
|
||||
char g_Other_buffer2[0x50000]; // 0xE7000
|
||||
OTTYPE g_OT1[OTSIZE]; // 0xF3000
|
||||
@ -371,7 +372,7 @@ int main(int argc, char** argv)
|
||||
|
||||
#ifdef USE_CRT_MALLOC
|
||||
_overlay_buffer = (char*)malloc(0x50000); // 0x1C0000
|
||||
_frontend_buffer = (char*)malloc(0x50000); // 0xFB400
|
||||
_frontend_buffer = (char*)malloc(0x60000); // 0xFB400
|
||||
_other_buffer = (char*)malloc(0x50000); // 0xF3000
|
||||
_other_buffer2 = (char*)malloc(0x50000); // 0xE7000
|
||||
_OT1 = (OTTYPE*)malloc(OTSIZE * sizeof(OTTYPE)); // 0xF3000
|
||||
@ -412,6 +413,9 @@ int main(int argc, char** argv)
|
||||
if (config)
|
||||
{
|
||||
const char* dataFolderStr = ini_get(config, "fs", "dataFolder");
|
||||
const char* userReplaysStr = ini_get(config, "game", "userChases");
|
||||
|
||||
InitUserReplays(userReplaysStr);
|
||||
|
||||
ini_sget(config, "render", "windowWidth", "%d", &windowWidth);
|
||||
ini_sget(config, "render", "windowHeight", "%d", &windowHeight);
|
||||
@ -422,7 +426,6 @@ int main(int argc, char** argv)
|
||||
ini_sget(config, "game", "drawDistance", "%d", &gDrawDistance);
|
||||
ini_sget(config, "game", "freeCamera", "%d", &enableFreecamera);
|
||||
ini_sget(config, "game", "driver1music", "%d", &gDriver1Music);
|
||||
|
||||
|
||||
if (dataFolderStr)
|
||||
{
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "ReadAVI.h" // WTF, ostream/fstream
|
||||
#include <EMULATOR.H>
|
||||
#include <EMULATOR_TIMER.H>
|
||||
#include "DRIVER2.H"
|
||||
|
||||
#include "C/PAD.H"
|
||||
#include "C/SYSTEM.H"
|
||||
#include "C/E3STUFF.H"
|
||||
#include "C/PRES.H"
|
||||
#include "C/PAUSE.H"
|
||||
|
||||
#include "STRINGS.H"
|
||||
@ -14,7 +14,257 @@
|
||||
#include <AL/al.h>
|
||||
#include <jpeglib.h>
|
||||
|
||||
struct UVWH
|
||||
{
|
||||
uchar u, v;
|
||||
uchar w, h;
|
||||
};
|
||||
|
||||
struct FMV_FONT
|
||||
{
|
||||
uchar u, v;
|
||||
uchar w, h;
|
||||
short unk1;
|
||||
};
|
||||
|
||||
// TODO: NEED SAVE
|
||||
UVWH fontUV[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 }
|
||||
};
|
||||
|
||||
FMV_FONT font[256];
|
||||
|
||||
// Partially decompiled function from FMV EXE
|
||||
void InitFMVFont()
|
||||
{
|
||||
int i;
|
||||
RECT16 fontRect;
|
||||
|
||||
Loadfile("FMV\\FONT.TIM", _other_buffer);
|
||||
|
||||
//fontRect.x = 512;
|
||||
//fontRect.y = 0;
|
||||
//fontRect.w = 384;
|
||||
//fontRect.h = 72;
|
||||
|
||||
//DrawSync(0);
|
||||
//LoadImage2(&fontRect,(u_long *)(_other_buffer + 20));
|
||||
//DrawSync(0);
|
||||
|
||||
DrawSync(0);
|
||||
LoadClut((u_long *)(_other_buffer + 20),960,72);
|
||||
DrawSync(0);
|
||||
|
||||
fontRect.x = 960;
|
||||
fontRect.y = 0;
|
||||
fontRect.w = 64;
|
||||
fontRect.h = 72;
|
||||
|
||||
LoadImage2(&fontRect,(u_long *)(_other_buffer + 64));
|
||||
DrawSync(0);
|
||||
|
||||
/*
|
||||
i = 0;
|
||||
while (i < 256)
|
||||
{
|
||||
font[i].u = fontUV[i].u + (fontUV[i].u >> 1);
|
||||
font[i].w = fontUV[i].w + (fontUV[i].w >> 1);
|
||||
|
||||
if (fontUV[i].w & 1)
|
||||
font[i].w += 1;
|
||||
|
||||
if (i == 46)
|
||||
font[i].w += 1;
|
||||
|
||||
if (font[i].u + font[i].w < 256)
|
||||
{
|
||||
font[i].unk1 = 0x108;
|
||||
}
|
||||
else if (font[i].u >= 256)
|
||||
{
|
||||
font[i].unk1 = 0x10c;
|
||||
}
|
||||
else if (font[i].u + font[i].w > 255)
|
||||
{
|
||||
font[i].unk1 = 0x109;
|
||||
font[i].u -= 64;
|
||||
}
|
||||
|
||||
//font[i].u = local_14;
|
||||
font[i].v = fontUV[i].v;
|
||||
font[i].h = fontUV[i].h;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
font[180].u = font[39].u;
|
||||
font[180].v = font[39].v;
|
||||
font[180].unk1 = font[39].unk1;
|
||||
font[146].u = font[39].u;
|
||||
font[146].v = font[39].v;
|
||||
font[146].unk1 = font[39].unk1;
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
while (i < 256)
|
||||
{
|
||||
font[i].u = fontUV[i].u;
|
||||
font[i].v = fontUV[i].v;
|
||||
font[i].w = fontUV[i].w;
|
||||
font[i].h = fontUV[i].h;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
POLY_FT4 fmvTextPolys[512];
|
||||
|
||||
// partially decompiled
|
||||
void PrintFMVText(char *str, int x, short y, int brightness)
|
||||
{
|
||||
char chr;
|
||||
char *ptr;
|
||||
int x_ofs;
|
||||
int i;
|
||||
int str_w;
|
||||
int drawnChars;
|
||||
OTTYPE ot;
|
||||
POLY_FT4* poly;
|
||||
|
||||
ClearOTagR((ulong*)&ot, 1);
|
||||
poly = fmvTextPolys;
|
||||
|
||||
str_w = 0;
|
||||
|
||||
if (brightness > 128)
|
||||
brightness = 128;
|
||||
|
||||
i = 0;
|
||||
while (chr = str[i], chr != 0)
|
||||
{
|
||||
if (chr == 32)
|
||||
str_w += 4;
|
||||
else
|
||||
str_w += font[chr].w;
|
||||
i++;
|
||||
}
|
||||
|
||||
x_ofs = x - str_w / 2;
|
||||
|
||||
drawnChars = 0;
|
||||
|
||||
ptr = (char *)str;
|
||||
while( true )
|
||||
{
|
||||
chr = *ptr;
|
||||
ptr++;
|
||||
|
||||
if (chr == 0 || drawnChars > 511)
|
||||
break;
|
||||
|
||||
if (chr == 32) // space
|
||||
{
|
||||
x_ofs += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
setPolyFT4(poly);
|
||||
|
||||
poly->x0 = x_ofs;
|
||||
poly->y0 = y;
|
||||
poly->x1 = x_ofs + font[chr].w;
|
||||
poly->y1 = y;
|
||||
poly->x2 = x_ofs;
|
||||
poly->y2 = y + font[chr].h;
|
||||
poly->x3 = x_ofs + font[chr].w;
|
||||
poly->y3 = y + font[chr].h;
|
||||
poly->u0 = font[chr].u;
|
||||
poly->v0 = font[chr].v;
|
||||
poly->u1 = font[chr].u + font[chr].w;
|
||||
poly->v1 = font[chr].v;
|
||||
poly->u2 = font[chr].u;
|
||||
poly->v2 = font[chr].v + font[chr].h;
|
||||
poly->u3 = font[chr].u + font[chr].w;
|
||||
poly->v3 = font[chr].v + font[chr].h;
|
||||
poly->tpage = getTPage(0,0, 960, 0);
|
||||
poly->clut = getClut(960, 72);
|
||||
|
||||
poly->r0 = brightness;
|
||||
poly->g0 = brightness;
|
||||
poly->b0 = brightness;
|
||||
|
||||
addPrim(&ot, poly);
|
||||
|
||||
x_ofs += font[chr].w;
|
||||
drawnChars++;
|
||||
poly++;
|
||||
}
|
||||
}
|
||||
|
||||
DrawOTag((ulong*)&ot);
|
||||
}
|
||||
|
||||
int UnpackJPEG(unsigned char* src_buf, unsigned src_length, unsigned bpp, unsigned char* dst_buf)
|
||||
{
|
||||
@ -164,6 +414,15 @@ void FMVPlayerInitGL()
|
||||
|
||||
void FMVPlayerShutdownGL()
|
||||
{
|
||||
RECT16 rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = 512;
|
||||
rect.h = 256;
|
||||
|
||||
ClearImage(&rect, 0, 0, 0);
|
||||
Emulator_SwapWindow();
|
||||
|
||||
Emulator_DestroyTexture(g_FMVTexture);
|
||||
}
|
||||
|
||||
@ -178,7 +437,7 @@ struct SUBTITLE
|
||||
char text[32];
|
||||
};
|
||||
|
||||
SUBTITLE g_Subtitles[512];
|
||||
SUBTITLE g_Subtitles[128];
|
||||
int g_NumSubtitles = 0;
|
||||
|
||||
void InitSubtitles(const char* filename)
|
||||
@ -188,7 +447,6 @@ void InitSubtitles(const char* filename)
|
||||
if (subFile)
|
||||
{
|
||||
fread(&g_NumSubtitles, sizeof(int), 1, subFile);
|
||||
printInfo("Subtitle text count: %d\n", g_NumSubtitles);
|
||||
|
||||
fread(g_Subtitles, sizeof(g_Subtitles), g_NumSubtitles, subFile);
|
||||
|
||||
@ -196,10 +454,59 @@ void InitSubtitles(const char* filename)
|
||||
}
|
||||
}
|
||||
|
||||
char* g_CreditsBuffer = NULL;
|
||||
char* g_CreditsLines[512];
|
||||
|
||||
void InitCredits(const char* filename)
|
||||
{
|
||||
memset(g_CreditsLines, 0, sizeof(g_CreditsLines));
|
||||
|
||||
FILE* credFile = fopen(filename, "rb");
|
||||
if (credFile)
|
||||
{
|
||||
fseek(credFile, 0, SEEK_END);
|
||||
int credits_buffer_size = ftell(credFile);
|
||||
fseek(credFile, 0, SEEK_SET);
|
||||
|
||||
g_CreditsBuffer = (char*)malloc(credits_buffer_size + 1);
|
||||
|
||||
fread(g_CreditsBuffer, 1, credits_buffer_size, credFile);
|
||||
g_CreditsBuffer[credits_buffer_size] = 0;
|
||||
|
||||
fclose(credFile);
|
||||
}
|
||||
|
||||
if(g_CreditsBuffer)
|
||||
{
|
||||
// make credits into lines
|
||||
char* str = g_CreditsBuffer;
|
||||
int numCreditsLines = 0;
|
||||
|
||||
while(*str)
|
||||
{
|
||||
if(!g_CreditsLines[numCreditsLines])
|
||||
g_CreditsLines[numCreditsLines] = str;
|
||||
|
||||
if(*str == '\r')
|
||||
{
|
||||
*str = '\0';
|
||||
|
||||
if (*++str == '\n')
|
||||
numCreditsLines++;
|
||||
}
|
||||
else if(*str == '\n')
|
||||
{
|
||||
*str = '\0';
|
||||
numCreditsLines++;
|
||||
}
|
||||
|
||||
str++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSubtitleText(SUBTITLE* sub)
|
||||
{
|
||||
gShowMap = 1;
|
||||
|
||||
char* str = sub->text;
|
||||
|
||||
// skip some trailing spaces
|
||||
@ -207,10 +514,7 @@ void PrintSubtitleText(SUBTITLE* sub)
|
||||
str++;
|
||||
}
|
||||
|
||||
SetTextColour(128, 128, 128);
|
||||
PrintString(str, (600 - StringWidth(str)) * 0x8000 >> 0x10, sub->y - 25);
|
||||
|
||||
gShowMap = 0;
|
||||
PrintFMVText(str, 256, sub->y - 25, 128);
|
||||
}
|
||||
|
||||
void DisplaySubtitles(int frame_number)
|
||||
@ -223,9 +527,46 @@ void DisplaySubtitles(int frame_number)
|
||||
}
|
||||
}
|
||||
|
||||
#define CREDITS_START_FRAME 700
|
||||
#define CREDITS_STOP_FRAME 5450
|
||||
#define CREDITS_FADE_START_FRAME 5900
|
||||
|
||||
void DisplayCredits(int frame_number)
|
||||
{
|
||||
int i;
|
||||
|
||||
int frame = frame_number;
|
||||
|
||||
if (frame > CREDITS_STOP_FRAME)
|
||||
frame = CREDITS_STOP_FRAME;
|
||||
|
||||
int height = (frame - CREDITS_START_FRAME) * 30 >> 5;
|
||||
|
||||
int fade = 0;
|
||||
if (frame_number > CREDITS_FADE_START_FRAME)
|
||||
{
|
||||
fade = (frame_number - CREDITS_FADE_START_FRAME) * 2;
|
||||
if (fade > 128)
|
||||
fade = 128;
|
||||
}
|
||||
|
||||
for(i = 0; i < 512; i++)
|
||||
{
|
||||
int text_h = 250 - height + i * 16;
|
||||
|
||||
if (text_h < -20 || text_h > 260)
|
||||
continue;
|
||||
|
||||
char* str = g_CreditsLines[i];
|
||||
|
||||
if(str)
|
||||
PrintFMVText(str, 256, text_h, 128 - fade);
|
||||
}
|
||||
}
|
||||
|
||||
extern void Emulator_Ortho2D(float left, float right, float bottom, float top, float znear, float zfar);
|
||||
|
||||
void DrawFrame(ReadAVI::stream_format_t& stream_format, int frame_number)
|
||||
void DrawFrame(ReadAVI::stream_format_t& stream_format, int frame_number, int credits)
|
||||
{
|
||||
int windowWidth, windowHeight;
|
||||
Emulator_GetScreenSize(windowWidth, windowHeight);
|
||||
@ -248,6 +589,11 @@ void DrawFrame(ReadAVI::stream_format_t& stream_format, int frame_number)
|
||||
|
||||
DisplaySubtitles(frame_number);
|
||||
|
||||
if(credits && frame_number >= CREDITS_START_FRAME)
|
||||
{
|
||||
DisplayCredits(frame_number);
|
||||
}
|
||||
|
||||
Emulator_EndScene();
|
||||
}
|
||||
|
||||
@ -261,7 +607,7 @@ void DoPlayFMV(RENDER_ARG* arg, int subtitles)
|
||||
sprintf(filename, "%sFMV\\%d\\RENDER%d.STR[0].AVI", gDataFolder, fd, arg->render);
|
||||
|
||||
ReadAVI readAVI(filename);
|
||||
|
||||
|
||||
// also load subtitle file
|
||||
if (subtitles)
|
||||
{
|
||||
@ -273,6 +619,12 @@ void DoPlayFMV(RENDER_ARG* arg, int subtitles)
|
||||
g_NumSubtitles = 0;
|
||||
}
|
||||
|
||||
if(arg->credits)
|
||||
{
|
||||
sprintf(filename, "%sDATA\\CREDITS.ENG", gDataFolder);
|
||||
InitCredits(filename);
|
||||
}
|
||||
|
||||
ReadAVI::avi_header_t avi_header = readAVI.GetAviHeader();
|
||||
|
||||
ReadAVI::stream_format_t stream_format = readAVI.GetVideoFormat();
|
||||
@ -294,8 +646,11 @@ void DoPlayFMV(RENDER_ARG* arg, int subtitles)
|
||||
alGenBuffers(4, audioStreamBuffers);
|
||||
alSourcei(audioStreamSource, AL_LOOPING, AL_FALSE);
|
||||
|
||||
int nextTime = SDL_GetTicks();
|
||||
int oldTime = nextTime;
|
||||
timerCtx_t fmvTimer;
|
||||
|
||||
Emulator_InitHPCTimer(&fmvTimer);
|
||||
|
||||
double nextFrameDelay = 0.0;
|
||||
|
||||
int frame_size;
|
||||
int queue_counter = 0;
|
||||
@ -303,20 +658,19 @@ void DoPlayFMV(RENDER_ARG* arg, int subtitles)
|
||||
int fade_out = 0;
|
||||
int done_frames = 0;
|
||||
|
||||
Emulator_GetHPCTime(&fmvTimer, 1);
|
||||
|
||||
// main loop
|
||||
while (true)
|
||||
{
|
||||
int curTime = SDL_GetTicks();
|
||||
int deltaTime = curTime - oldTime;
|
||||
double delta = Emulator_GetHPCTime(&fmvTimer, 1);
|
||||
|
||||
if (deltaTime > 1000)
|
||||
{
|
||||
nextTime += deltaTime;
|
||||
oldTime = curTime;
|
||||
}
|
||||
if (delta > 1.0)
|
||||
delta = 0.0;
|
||||
|
||||
nextFrameDelay -= delta;
|
||||
|
||||
if (curTime <= nextTime) // wait for frame
|
||||
if (nextFrameDelay > 0) // wait for frame
|
||||
{
|
||||
Emulator_EndScene();
|
||||
continue;
|
||||
@ -351,16 +705,16 @@ void DoPlayFMV(RENDER_ARG* arg, int subtitles)
|
||||
int ret = UnpackJPEG(frame_entry.buf, frame_size, stream_format.bits_per_pixel, (unsigned char*)_frontend_buffer);
|
||||
|
||||
if (ret == 0)
|
||||
DrawFrame(stream_format, done_frames);
|
||||
{
|
||||
DrawFrame(stream_format, done_frames, arg->credits);
|
||||
}
|
||||
|
||||
// set next step time
|
||||
if (g_swapInterval == 0)
|
||||
nextTime = curTime;
|
||||
if (g_swapInterval == 1)
|
||||
nextFrameDelay += double(avi_header.TimeBetweenFrames) / 1000000.0;
|
||||
else
|
||||
nextTime += avi_header.TimeBetweenFrames / 1000;
|
||||
|
||||
oldTime = curTime;
|
||||
|
||||
nextFrameDelay = 0.0;
|
||||
|
||||
done_frames++;
|
||||
}
|
||||
else if (frame_entry.type == ReadAVI::ctype_audio_data)
|
||||
@ -400,7 +754,7 @@ void DoPlayFMV(RENDER_ARG* arg, int subtitles)
|
||||
if (queue_counter < 4)
|
||||
QueueAudioBuffer(audioStreamBuffers[queue_counter++], audioStreamSource, frame_entry, audio_format, 0, frame_size);
|
||||
|
||||
if(queue_counter > 0 && state != AL_PLAYING)
|
||||
if((queue_counter > 1 || numProcessed == -1) && state != AL_PLAYING)
|
||||
alSourcePlay(audioStreamSource);
|
||||
}
|
||||
}
|
||||
@ -423,14 +777,27 @@ int FMV_main(RENDER_ARGS* args)
|
||||
DRAWENV draw;
|
||||
|
||||
FMVPlayerInitGL();
|
||||
LoadFont(NULL);
|
||||
//LoadFont(NULL);
|
||||
|
||||
InitFMVFont();
|
||||
|
||||
SetupDefDrawEnv(&draw, 0, 0, 512, 256);
|
||||
SetupDefDispEnv(&disp, 0, 0, 512, 256);
|
||||
|
||||
SetupDefDrawEnv(&draw, 0, 0, 600, 250);
|
||||
SetupDefDispEnv(&disp, 0, 0, 600, 250);
|
||||
draw.dfe = 1;
|
||||
|
||||
draw.clip.x = -512;
|
||||
draw.clip.w = 1200;
|
||||
draw.clip.y = -1;
|
||||
draw.clip.h = 512;
|
||||
|
||||
disp.isinter = 0;
|
||||
|
||||
PutDrawEnv(&draw);
|
||||
PutDispEnv(&disp);
|
||||
|
||||
Emulator_SetupClipMode(draw.clip);
|
||||
|
||||
for (int i = 0; i < args->nRenders; i++)
|
||||
{
|
||||
DoPlayFMV(&args->Args[i], args->subtitle);
|
||||
@ -438,6 +805,10 @@ int FMV_main(RENDER_ARGS* args)
|
||||
|
||||
FMVPlayerShutdownGL();
|
||||
|
||||
if (g_CreditsBuffer)
|
||||
free(g_CreditsBuffer);
|
||||
g_CreditsBuffer = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user