aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code
diff options
context:
space:
mode:
authorbrunzelchen <brunzelchen@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-04 16:52:49 +0000
committerbrunzelchen <brunzelchen@b956fd51-792f-4845-bead-9b4dfca2ff2c>2010-04-04 16:52:49 +0000
commit19702a2272a014fe62256b1ddfd8f5068feb35d0 (patch)
treeb7285d50933ba195c53090f4e3d8576de5530b22 /Game/Code
parentfaf53d1dadd8e943d3cf3e4c4b1138b539ee55d4 (diff)
downloadusdx-19702a2272a014fe62256b1ddfd8f5068feb35d0.tar.gz
usdx-19702a2272a014fe62256b1ddfd8f5068feb35d0.tar.xz
usdx-19702a2272a014fe62256b1ddfd8f5068feb35d0.zip
performance mode for videos: reducing lines on low fps
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/1.0.1 Challenge MOD@2213 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Game/Code')
-rw-r--r--Game/Code/Classes/UIni.pas13
-rw-r--r--Game/Code/Classes/UVideo.pas222
-rw-r--r--Game/Code/Menu/UDisplay.pas40
-rw-r--r--Game/Code/UltraStar.dpr2
4 files changed, 233 insertions, 44 deletions
diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas
index 3cfd2430..df291ec3 100644
--- a/Game/Code/Classes/UIni.pas
+++ b/Game/Code/Classes/UIni.pas
@@ -37,6 +37,7 @@ type
MovieSize: integer;
MoviePreview: integer;
AspectCorrect: integer;
+ PerformanceMode:integer;
// Sound
MicBoost: integer;
@@ -136,7 +137,8 @@ const
ISpectrograph: array[0..1] of string = ('Off', 'On');
IMovieSize: array[0..3] of string = ('Half', 'Full', 'Preview only', 'Off');
IMoviePreview: array[0..1] of string = ('Off', 'On');
- IAspectCorrect: array[0..2] of String = ('Stretch', 'Crop', 'LetterBox');
+ IAspectCorrect: array[0..2] of String = ('Stretch', 'Crop', 'LetterBox');
+ IPerformanceMode:array[0..1] of string = ('Off', 'On');
IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB');
IClickAssist: array[0..1] of string = ('Off', 'On');
@@ -361,6 +363,11 @@ begin
for Pet := 0 to High(IAspectCorrect) do
if Tekst = IAspectCorrect[Pet] then Ini.AspectCorrect := Pet;
+ // PerformanceMode
+ Tekst := IniFile.ReadString('Graphics', 'PerformanceMode', IPerformanceMode[1]);
+ for Pet := 0 to High(IPerformanceMode) do
+ if Tekst = IPerformanceMode[Pet] then Ini.PerformanceMode := Pet;
+
// MicBoost
Tekst := IniFile.ReadString('Sound', 'MicBoost', 'Off');
for Pet := 0 to High(IMicBoost) do
@@ -686,6 +693,10 @@ begin
Tekst := IAspectCorrect[Ini.AspectCorrect];
IniFile.WriteString('Graphics', 'AspectCorrect', Tekst);
+ // PerformanceMode
+ Tekst := IPerformanceMode[Ini.PerformanceMode];
+ IniFile.WriteString('Graphics', 'PerformanceMode', Tekst);
+
// MicBoost
Tekst := IMicBoost[Ini.MicBoost];
IniFile.WriteString('Sound', 'MicBoost', Tekst);
diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas
index 94c58060..68b892c8 100644
--- a/Game/Code/Classes/UVideo.pas
+++ b/Game/Code/Classes/UVideo.pas
@@ -27,6 +27,7 @@ uses SDL,
math,
gl,
glu,
+ glext,
SysUtils,
{$ifdef DebugDisplay}
{$ifdef win32}
@@ -35,6 +36,10 @@ uses SDL,
{$ENDIF}
UIni;
+const
+ //PIXEL_FORMAT = GL_RGB;
+ numBytes = 3;
+
type
TRectCoords = record //from 1.1
Left, Right: double;
@@ -44,6 +49,8 @@ type
TAspectCorrection = (acoStretch, acoCrop, acoLetterBox); //from 1.1
+
+
procedure Init;
procedure acOpenFile(FileName: pAnsiChar);
procedure acClose;
@@ -59,11 +66,17 @@ procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords; Window: TRectCoords
procedure SetAspectCorrection(aspect: TAspectCorrection);
procedure ResetAspectCorrection;
+
+
var
VideoOpened, VideoPaused: Boolean;
VideoTex: glUint;
- TexData: array of Byte;
+ //TexData: array of Byte;
VideoStreamIndex: Integer;
+ SkipLines: Integer;
+ LastSkipLines: Integer;
+ mmfps: Real;
+ Counter: Integer;
//myBuffer: pByte;
TexX, TexY, dataX, dataY: Cardinal;
VideoTimeBase, VideoTime, LastFrameTime, TimeDifference, NegativeSkipTime: Extended;
@@ -89,10 +102,12 @@ var
mtime: PChar; //for debug
mtime_str: string; //for debug
+ pbo: glUint;
+ pbo_supported: boolean;
implementation
uses
- UGraphic, ULog;
+ UGraphic, ULog, UDisplay;
function read_proc(sender: Pointer; buf: PByte; size: integer): integer; cdecl;
begin
@@ -115,10 +130,20 @@ begin
VideoPaused:=False;
fName := '';
- glGenTextures(1, PglUint(@VideoTex));
- SetLength(TexData,0);
+ glGenTextures(1, @VideoTex);
+
+ //pbo_supported := glext_LoadExtension('GL_ARB_pixel_buffer_object') and
+ // glext_LoadExtension('GL_version_1_5');
+ pbo_supported := false;
+ if (pbo_supported) then
+ glGenBuffers(1, @pbo);
+
+ //SetLength(TexData,0);
fAspectCorrection := TAspectCorrection(Ini.AspectCorrect);
+ SkipLines := 0;
+ LastSkipLines := 0;
+ Counter := 0;
end;
procedure acOpenFile(FileName: pAnsiChar);
@@ -129,7 +154,7 @@ begin
VideoPaused := False;
VideoTimeBase := 0;
- rTimeBase:=0;
+ rTimeBase := 0;
VideoTime := 0;
LastFrameTime := 0;
TimeDifference := 0;
@@ -188,7 +213,9 @@ begin
TexY := videodecoder^.stream_info.additional_info.video_info.frame_height;
dataX := Round(Power(2, Ceil(Log2(TexX))));
dataY := Round(Power(2, Ceil(Log2(TexY))));
- SetLength(TexData,TexX*TexY*3);
+ //SetLength(TexData, TexX*numBytes);
+ //for I := 0 to TexX*numBytes - 1 do
+ // TexData[I]:=0;
// calculate some information for video display
VideoAspect:=videodecoder^.stream_info.additional_info.video_info.pixel_aspect;
@@ -201,14 +228,32 @@ begin
VideoTimeBase:=info.additional_info.video_info.frames_per_second;
- //from 1.1
glBindTexture(GL_TEXTURE_2D, VideoTex);
- glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0,
- GL_RGB, GL_UNSIGNED_BYTE, nil);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, nil);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ if(pbo_supported) then
+ begin
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, numBytes*TexX*TexY, nil, GL_STREAM_DRAW);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ end;
+
+ //SkipLines := 0;
+ //LastSkipLines := 0;
+ //Counter := 0;
+ mmfps := 50;
end;
procedure acClose;
@@ -223,7 +268,7 @@ begin
inst := nil;
fs.Free;
fs:=nil;
- SetLength(TexData,0);
+ //SetLength(TexData,0);
VideoOpened:=False;
fName := '';
end;
@@ -382,11 +427,15 @@ var
FrameFinished: Integer;
errnum, x, y: Integer;
FrameDataPtr: PByteArray;
+ FrameDataPtr2: PByteArray;
linesize: integer;
myTime: Extended;
DropFrame: Boolean;
droppedFrames: Integer;
I, J: Integer;
+
+ glError: glEnum;
+ glErrorStr: String;
const
FRAMEDROPCOUNT=3;
begin
@@ -479,14 +528,118 @@ begin
end;
errnum:=1; //TODO!!
- if errnum >=0 then begin
- FrameDataPtr:=Pointer(videodecoder^.buffer);
+ if errnum >=0 then
+ begin
+ mmfps := (Display.mFPS+mmfps)/2;
+ if(Ini.PerformanceMode=1) then
+ begin
+ if (mmfps<45) then
+ begin
+ if(SkipLines<3) and (Counter<100) then
+ Counter := round(Counter+70/mmfps)
+ else if (SkipLines<3) and (Counter>=100) then
+ begin
+ Inc(SkipLines);
+ mmfps:=50;
+ Counter := 0;
+ end;
+ end else if (mmfps>75) then
+ begin
+ if(SkipLines>0) and (Counter<=100) then
+ Counter := round(Counter+50/mmfps)
+ else if (SkipLines>0) and (Counter>=100) then
+ begin
+ Dec(SkipLines);
+ LastSkipLines := SkipLines;
+ Counter := 0;
+ end;
+ end else Counter := 0;
+ end;
- glBindTexture(GL_TEXTURE_2D, VideoTex);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY, GL_RGB, GL_UNSIGNED_BYTE, @FrameDataPtr[0]);
+ if(not pbo_supported) then
+ begin
+ FrameDataPtr:=Pointer(videodecoder^.buffer);
+
+ glBindTexture(GL_TEXTURE_2D, VideoTex);
+
+ if(SkipLines>0)then
+ begin
+ for I := 0 to TexY - 1 do
+ begin
+ if(I mod (SkipLines+1) = 0) then
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (I div (SkipLines+1)), TexX, 1,
+ GL_RGB, GL_UNSIGNED_BYTE, @FrameDataPtr[I*numBytes*TexX]);
+ end;
+ end else
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY,
+ GL_RGB, GL_UNSIGNED_BYTE, @FrameDataPtr[0]);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ end else
+ begin
+ glGetError();
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
+
+ glError := glGetError;
+ if glError <> GL_NO_ERROR then
+ begin
+ acClose;
+ Log.LogError('Error drawing Video "glBindBuffer"');
+ Exit;
+ end;
+
+ FrameDataPtr := glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
+ glError := glGetError;
+ if glError <> GL_NO_ERROR then
+ begin
+ acClose;
+ Log.LogError('Error drawing Video pbo "glMapBuffer"');
+ Exit;
+ end;
+
+ FrameDataPtr2:=Pointer(videodecoder^.buffer);
+ move(FrameDataPtr2[0], FrameDataPtr[0], numBytes*TexX*TexY);
+
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
+ glError := glGetError;
+ if glError <> GL_NO_ERROR then
+ begin
+ acClose;
+ Log.LogError('Error drawing Video pbo "glUnmapBuffer"');
+ Exit;
+ end;
+
+ glBindTexture(GL_TEXTURE_2D, VideoTex);
+ glError := glGetError;
+ if glError <> GL_NO_ERROR then
+ begin
+ acClose;
+ Log.LogError('Error drawing Video pbo "glBindTexture"');
+ Exit;
+ end;
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexX, TexY,
+ GL_RGB, GL_UNSIGNED_BYTE, 0);
+ glError := glGetError;
+ if glError <> GL_NO_ERROR then
+ begin
+ acClose;
+ case glError of
+ GL_INVALID_ENUM: glErrorStr:='INVALID_ENUM';
+ GL_INVALID_VALUE: glErrorStr:='INVALID_VALUE';
+ GL_INVALID_OPERATION: glErrorStr:='INVALID_OPERATION';
+ GL_STACK_OVERFLOW: glErrorStr:='STACK_OVERFLOW';
+ GL_STACK_UNDERFLOW: glErrorStr:='STACK_UNDERFLOW';
+ GL_OUT_OF_MEMORY: glErrorStr:='OUT_OF_MEMORY';
+ else glErrorStr:='unknown error';
+ end;
+ Log.LogError('Error drawing Video pbo "glTexSubImage2D" ('+glErrorStr+')');
+ Exit;
+ end;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ end;
VideoTime := videodecoder^.timecode;
if Ini.Debug = 1 then
@@ -588,7 +741,7 @@ begin
TexRect.Left := 0;
TexRect.Right := TexX / dataX;
TexRect.Upper := 0;
- TexRect.Lower := TexY / dataY;
+ TexRect.Lower := (TexY/(SkipLines+1)) / dataY;
end;
procedure acDrawGL(Screen: integer);
@@ -608,12 +761,23 @@ var
text: string;
test: PChar;
ScreenRect, TexRect: TRectCoords;
+ FrameDataPtr: PByteArray;
+ FrameDataPtr2: PByteArray;
+ Offset: Integer;
+
begin
// have a nice black background to draw on (even if there were errors opening the vid)
if (Screen=1) and not Window.windowed then begin
- glClearColor(0,0,0,0);
+ glDisable(GL_BLEND);
+ //glDisable(GL_DEPTH_TEST);
+ //glDepthMask(GL_FALSE);
+ //glDisable(GL_CULL_FACE);
+
+ glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end;
+ end else
+ glEnable(GL_BLEND);
+
// exit if there's nothing to draw
if not VideoOpened then Exit;
// if we're still inside negative skip, then exit
@@ -621,7 +785,7 @@ begin
GetVideoRect(ScreenRect, TexRect, Window);
- glEnable(GL_BLEND);
+
glScissor(round((Window.Left)*(ScreenW/Screens)/RenderW+(ScreenW/Screens)*(Screen-1)),
round((RenderH-Window.Lower)*ScreenH/RenderH),
@@ -633,6 +797,7 @@ begin
glEnable(GL_TEXTURE_2D);
glColor4f(1, 1, 1, Blend);
glBindTexture(GL_TEXTURE_2D, VideoTex);
+
glbegin(gl_quads);
// upper-left coord
glTexCoord2f(TexRect.Left, TexRect.Upper);
@@ -649,6 +814,7 @@ begin
glEnd;
glDisable(GL_TEXTURE_2D);
+ //glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
@@ -706,31 +872,37 @@ begin
glColor4f(0, 0, 0, 0.2);
glbegin(gl_quads);
glVertex2f(0, 50);
- glVertex2f(0, 140);
- glVertex2f(250, 140);
+ glVertex2f(0, 160);
+ glVertex2f(250, 160);
glVertex2f(250, 50);
glEnd;
glColor4f(1,1,1,1);
SetFontStyle (1);
SetFontItalic(False);
- SetFontSize(9);
+ SetFontSize(7);
SetFontPos (5, 50);
text:= 'vtime: ' + FormatFloat('#0.00', VideoTime);
test := Addr(text[1]);
glPrint(test);
- SetFontPos (5, 70);
+ SetFontPos (5, 65);
//text:= 'vtime: ' + FormatFloat('#0.00', videodecoder^.timecode);
//test := Addr(text[1]);
glPrint(timediff);
- SetFontPos (5, 90);
+ SetFontPos (5, 80);
glPrint(mtime);
- SetFontPos (5, 110);
+ SetFontPos (5, 95);
case fAspectCorrection of
acoCrop : glPrint('Crop');
acoStretch : glPrint('Stretch');
acoLetterBox : glPrint('LetterBox');
end;
+
+ SetFontPos (5, 110);
+ glPrint(PChar('mmfps: '+FormatFloat('#0.00', mmfps)));
+
+ SetFontPos (5, 125);
+ glPrint(PChar('skipL: '+inttostr(SkipLines)));
end;
end;
diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas
index 4612b361..56fa8ce1 100644
--- a/Game/Code/Menu/UDisplay.pas
+++ b/Game/Code/Menu/UDisplay.pas
@@ -32,6 +32,7 @@ type
//FPS Counter
FPSCounter: Cardinal;
LastFPS: Cardinal;
+ mFPS: Real;
NextFPSSwap:Cardinal;
//For Debug OSD
@@ -121,6 +122,7 @@ var
currentTime: Cardinal;
glError: glEnum;
glErrorStr: String;
+ Ticks: Cardinal;
// end
begin
Result := True;
@@ -298,6 +300,19 @@ begin
end;
end; // if
+ //Calculate FPS
+ Ticks := GetTickCount;
+ if (Ticks >= NextFPSSwap) then
+ begin
+ LastFPS := FPSCounter * 4;
+
+ mFPS := (mFPS+LastFPS)/2;
+
+ FPSCounter := 0;
+ NextFPSSwap := Ticks + 250;
+ end;
+ Inc(FPSCounter);
+
//Draw OSD only on first Screen if Debug Mode is enabled
if ((Ini.Debug = 1) OR (Params.Debug)) AND (S=1) then
DrawDebugInformation;
@@ -408,17 +423,16 @@ end;
// DrawDebugInformation - Procedure draw FPS and some other Informations on Screen
//------------
procedure TDisplay.DrawDebugInformation;
-var Ticks: Cardinal;
begin
//Some White Background for information
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glColor4f(1, 1, 1, 0.5);
glBegin(GL_QUADS);
- glVertex2f(690, 44);
+ glVertex2f(690, 57);
glVertex2f(690, 0);
glVertex2f(800, 0);
- glVertex2f(800, 44);
+ glVertex2f(800, 57);
glEnd;
glDisable(GL_BLEND);
@@ -428,29 +442,21 @@ begin
SetFontItalic(False);
glColor4f(0, 0, 0, 1);
- //Calculate FPS
- Ticks := GetTickCount;
- if (Ticks >= NextFPSSwap) then
- begin
- LastFPS := FPSCounter * 4;
- FPSCounter := 0;
- NextFPSSwap := Ticks + 250;
- end;
-
- Inc(FPSCounter);
-
//Draw Text
//FPS
SetFontPos(695, 0);
- glPrint (PChar('FPS: ' + InttoStr(LastFPS)));
+ glPrint (PChar('aFPS: ' + InttoStr(LastFPS)));
- //RSpeed
SetFontPos(695, 13);
+ glPrint (PChar('mFPS: ' + InttoStr(round(mFPS))));
+
+ //RSpeed
+ SetFontPos(695, 26);
glPrint (PChar('RSpeed: ' + InttoStr(Round(1000 * TimeMid))));
//LastError
- SetFontPos(695, 26);
+ SetFontPos(695, 39);
glColor4f(1, 0, 0, 1);
glPrint (PChar(OSD_LastError));
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
index ee158733..f8f8b397 100644
--- a/Game/Code/UltraStar.dpr
+++ b/Game/Code/UltraStar.dpr
@@ -124,7 +124,7 @@ uses
acinerella in 'lib\acinerella\acinerella.pas';
const
- Version = 'UltraStar Deluxe v1.0.1a Challenge-MOD r7b beta 2010-03-18';
+ Version = 'UltraStar Deluxe v1.0.1a Challenge-MOD r7b beta 2 2010-04-04';
var
WndTitle: string;