ColorTrixMovieCommandImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, January 16, 1987 4:59:51 pm PST
DIRECTORY Args, CedarProcess, ColorTrixBasics, ColorTrixDispatch, ColorTrixFile, Commander, Controls, ImagerPixelMap, Process, Real, Rope, Terminal;
ColorTrixMovieCommandImpl: CEDAR PROGRAM
IMPORTS Args, CedarProcess, ColorTrixBasics, ColorTrixDispatch, ColorTrixFile, Controls, Process, Real, Terminal
~ BEGIN
ROPE:     TYPE ~ Rope.ROPE;
PixelMap:    TYPE ~ ColorTrixBasics.PixelMap;
PixelMapMisc:  TYPE ~ ColorTrixBasics.PixelMapMisc;
DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle;
MovieData:   TYPE ~ REF MovieDataRec;
MovieDataRec:  TYPE ~ MONITORED RECORD [
x, y, w, h, nFrames:   NAT ← 0,
nRows, nCols:     NAT ← 0,
speed, frame:      Controls.Control ← NIL,
outer:        Controls.Viewer ← NIL,
outerData:      Controls.OuterData ← NIL,
frames, show, save:    PixelMapMisc,
now:        REAL ← 0.0,
nFrame:       INTEGER ← 0,
pause, pauseSave:    BOOLFALSE,
bounce:       BOOLFALSE,
forward, forwardSave:   BOOLTRUE
];
CtMovie: PUBLIC Commander.CommandProc ~ {
ok: BOOL;
x, y, w, h, nFrames, clear, name: Args.Arg;
[ok, x, y, w, h, nFrames, clear, name] ← Args.ArgsGet[cmd, "%iiiii-clear%b-name%s"];
IF NOT ok
THEN RETURN[$Failure, NIL]
ELSE {
cd: PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
m: MovieData ← NEW[MovieDataRec];
m.x ← x.int;
m.y ← y.int;
m.w ← w.int;
m.h ← h.int;
m.nFrames ← nFrames.int;
m.show ← ColorTrixBasics.SetPmMiscWindow[cd, (cd.w-m.w)/2, (cd.h-m.h)/2, m.w, m.h];
IF name.ok
THEN {
m.frames ← ColorTrixFile.ReadFile[name.rope];
[m.nCols, m.nRows] ← NRowsCols[m.frames, m.nFrames, m.x, m.w];
}
ELSE {
[m.nCols, m.nRows] ← NRowsCols[cd, m.nFrames, m.x, m.w];
cd ← ColorTrixBasics.SetPmMiscWindow[
cd, 0, 0, m.nCols*m.w, MIN[cd.h, m.nRows*m.h]];
m.frames ← ColorTrixBasics.CreatePmMisc[cd.bpp, cd.x, cd.y, cd.w, cd.h];
ColorTrixBasics.CopyPmMisc[cd, m.frames];
};
m.speed ← Controls.NewControl["Speed", hSlider, m, -1.0, 1.0, 0.1,,,,,,,,,,,, LIST[[0.0, 0.0]]];
m.frame ← Controls.NewControl["Frame", hSlider, m, 0, nFrames.int-1,0, Frame,,TRUE];
m.outer ← Controls.OuterViewer[
data: m,
column: right,
name: "Ct Movie",
destroyProc: DestroyProc,
controls: LIST[m.speed, m.frame],
buttons: LIST [["Forward", Forward], ["Bounce-Off", Bounce], ["Pause", Pause]]
];
m.outerData ← NARROW[m.outer.data];
IF clear.ok AND clear.bool THEN ColorTrixBasics.FillPmMisc[cd];
ColorTrixBasics.CopyPmMisc[m.show, m.save ←
ColorTrixBasics.CreatePmMisc[cd.bpp, m.show.x, m.show.y, m.show.w, m.show.h]];
TRUSTED {Process.Detach[FORK Movie[m]]};
};
};
NRowsCols: PROC [pm: PixelMapMisc, nFrames, x, w: NAT]
RETURNS [nCols, nRows: NAT] ~ {
nCols ← MIN[nFrames, (pm.w-x)/w];
nRows ← nFrames/nCols+MIN[1, nFrames MOD nCols];
};
DestroyProc: Controls.DestroyProc ~ {NARROW[outerData.data, MovieData].pause ← FALSE};
ShowNFrame: PROC [m: MovieData] ~ {
SetNFrame[m];
Terminal.WaitForBWVerticalRetrace[Terminal.Current[]];
ColorTrixBasics.CopyClippedPmMisc[
m.frames, m.show,
m.x+(m.nFrame MOD m.nCols)*m.w,
m.y+(m.nFrame/m.nCols)*m.h,
m.w, m.h];
IF NOT m.pause THEN Controls.SetSliderDialValue[m.frame, m.nFrame];
};
SetNFrame: PROC [m: MovieData] ~ {
IF (m.nFrame ← Real.RoundI[m.now]) IN [0..m.nFrames) THEN RETURN;
IF m.bounce
THEN {
m.forward ← NOT m.forward;
m.nFrame ← IF m.nFrame < 0 THEN 0 ELSE m.nFrames-1;
}
ELSE {
IF m.nFrame >= m.nFrames THEN m.now ← m.nFrame ← 0;
IF m.nFrame < 0 THEN m.now ← m.nFrame ← m.nFrames-1;
};
};
Frame: Controls.ControlProc ~ {
m: MovieData ~ NARROW[control.data];
IF control.mouse.state = down THEN {m.pauseSave ← m.pause; m.pause ← TRUE};
m.now ← control.value;
ShowNFrame[m];
IF control.mouse.state = up THEN m.pause ← m.pauseSave;
};
Movie: PROC [m: MovieData] ~ {
CedarProcess.SetPriority[background];
WHILE NOT m.outerData.destroyed DO
IF m.pause THEN {Process.Pause[Process.MsecToTicks[150]]; LOOP};
m.now ← m.now+(IF m.forward THEN m.speed.value ELSE -m.speed.value);
ShowNFrame[m];
ENDLOOP;
ColorTrixBasics.CopyPmMisc[m.save, m.show];
};
Pause: Controls.ClickProc ~ {
m: MovieData ~ NARROW[NARROW[clientData, Controls.OuterData].data];
m.pause ← NOT m.pause;
Controls.ButtonStyle[
m.outerData, "Pause", IF m.pause THEN $WhiteOnBlack ELSE $BlackOnWhite];
};
Bounce: Controls.ClickProc ~ {
m: MovieData ~ NARROW[NARROW[clientData, Controls.OuterData].data];
Controls.ButtonToggle[m.outerData, m.bounce ← NOT m.bounce, "Bounce-On", "Bounce-Off"];
IF m.bounce THEN m.forwardSave ← m.forward ELSE m.forward ← m.forwardSave;
};
Forward: Controls.ClickProc ~ {
m: MovieData ~ NARROW[NARROW[clientData, Controls.OuterData].data];
m.forward ← m.forwardSave ← NOT m.forward;
Controls.ButtonToggle[m.outerData, m.forward, "Forward", "Reverse"];
};
Start Code
ColorTrixDispatch.RegisterCtOp["Movie", CtMovie, "Ct Movie <x y w h nFrames> [-clear]."];
END.