{########################################
 ##          -= JSM ENGINE =-          ##
 ##                                    ##
 ##   Start Date:  12/10/2009          ##
 ##   Last Modify: 12/07/2011          ##
 ##   End Date:    __/__/____          ##
 ##                                    ##
 ##                                    ##
 ##  Copyright 2009-2011 by JSM        ##
 ##  John_Moff@yahoo.com               ##
 ########################################}
 
unit JSMEngine;

interface

uses
  Windows, Direct3D9;

const
  EngDLL = 'JSM.DLL';

////    COLORS, EFFECTS, etc...    ////

  Red      = $fFFf0000; ARed     = $fFFf6600;
  FRed     = $fFFf4600; F2Red    = $f99f3900;
  Lime     = $f00fFF00; Green    = $f00f9900;
  Blue     = $f00f00FF; LBlue    = $fFBfFEFF;
  Yellow   = $fFFfFF00; Orange   = $fFFf9900;
  Fuchsia  = $fFFf00FF; BYellow  = $fFFfE000;
  Violet   = $fDEf00FF; LYellow  = $fFFfFF88;
  Black    = $f00f0000; White    = $fFFfFFFF;
  LSilver  = $f99f9999; DSilver  = $f33f3333;
  LRed     = $fFFf0050;

  FX_NORM =  $01;  FX_ADD  = $02;  FX_SADD = $03;  FX_SCOL = $04;  FX_SCOLADD = $05;
  FX_MUL  =  $06;  FX_MULA = $07;  FX_IMUL = $08;  FX_IMULA = $09; FX_INV = $010;
  FX_SBR  = $011;  FX_DBR  = $012; FX_ISBR = $013; FX_DSBR = $014; FX_NONE = $015;

  F_NONE        = $001;
  F_BILINEAR    = $002;

////   FLAGS FOR RENDER    ////

  NONE  = $00000;
  CAM   = $00001;

////    KEYBOARD STATS    ////

  KeyA = 65; KeyB = 66; KeyC = 67; KeyD = 68; KeyE = 69; KeyF = 70; KeyG = 71;
  KeyH = 72; KeyI = 73; KeyJ = 74; KeyK = 75; KeyL = 76; KeyM = 77; KeyN = 78;
  KeyO = 79; KeyP = 80; KeyQ = 81; KeyR = 82; KeyS = 83; KeyT = 84; KeyU = 85;
  KeyV = 86; KeyW = 87; KeyX = 88; KeyY = 89; KeyZ = 90;

  KeyLEFT = 37; KeyUP = 38; KeyRIGHT = 39; KeyDOWN = 40;

  Key0 = 48; Key1 = 49; Key2 = 50; Key3 = 51; Key4 = 52;
  Key5 = 53; Key6 = 54; Key7 = 55; Key8 = 56; Key9 = 57;

  KeyF1 = 112; KeyF2 = 113;  KeyF3 = 114;  KeyF4 = 115;
  KeyF5 = 116; KeyF6 = 117;  KeyF7 = 118;  KeyF8 = 119;
  KeyF9 = 120; KeyF10 = 121; KeyF11 = 122; KeyF12 = 123;

  KeyBACKSPACE = 8; KeyTAB = 9;  KeyENTER = 13;  KeySHIFT = 16;
  KeyCTRL     = 17; KeyALT = 18; KeyESCAPE = 27; KeySPACE = 32;

  KeyPAGEUP   = 33; KeyPAGEDOWN = 34; KeyEND = 35; KeyHOME = 36;
  KeySNAPSHOT = 44; KeyINSERT   = 45; KeyDELETE = 46;

  KeyNUM0 = 96;  KeyNUM1 = 97;  KeyNUM2 = 98;  KeyNUM3 = 99;  KeyNUM4 = 100;
  KeyNUM5 = 101; KeyNUM6 = 102; KeyNUM7 = 103; KeyNUM8 = 104; KeyNUM9 = 105;
  KeyMULT = 106; KeyADD  = 107; KeySEP  = 108; KeySUB  = 109; KeyDEC  = 110;
  KeyDIV  = 111;


/// SPRITE RECORD ///
type
TEngObj = {packed} record
  X, Y, VX, VY, Width, Height,
  Radius, Way, Angle, ACC, Life, Speed, Mass, Frame : Single;
  Name : String;
  Color : Cardinal;
  Image : Integer;
  Alpha, FX, _Type : byte;
  Dead, Active, Rotate, Change : boolean;
end;


/// JSM Font ///
var
JFont: record
  Tex, Size, xOff, yOff: Integer;
end;


type
  TRenderProc = procedure();
  TUpdateProc = procedure();

const
  M_RightB = 0;
  M_LeftB  = 1;
  M_MidB   = 2;

/// JSM CORE ///
type
IJSMEng = interface
  procedure Init(Width, Height: integer; UWnd: HWND; Fullscreen, Show_Cursor, ShowLogo: Boolean; TexFilter:byte); stdcall;
  procedure RenderProc (Process: TRenderProc); stdcall;
  procedure UpdateProc (Process: TUpdateProc);stdcall;
  procedure EngineLoop; stdcall;
  function  GetFPS    ():Integer; stdcall;
  function  GetWidth  ():Integer; stdcall;
  function  GetHeight ():Integer; stdcall;
  procedure CloseEngine; stdcall;
  procedure ShowText(X,Y:Integer; Text: String; Color: Cardinal); stdcall;
end;
procedure CreateEngine(out Engine: IJSMEng); stdcall; external EngDLL;
/// ////// ///

/// Render 2D ///
type
  IR2D = interface
  procedure UpdateCamera (X,Y,Angle: Single); stdcall;
  function  AddTexture   (Name: String; Tex: IDirect3DTexture9; ID,Width,Height,FWidth,FHeight: Integer): Integer; stdcall;
  function  LoadTexture  (FileName : String; FWidth, FHeight:Integer): integer;stdcall;

  procedure Render4      (X,Y,Width,Height,Angle: Single; Texture,Flags: Integer); stdcall;
  procedure Render4A     (X,Y,Width,Height,Angle,Frame: Single; Texture,Flags: Integer); stdcall;
  procedure Render4Ex    (X,Y,Width,Height,Angle: Single; Effect,Alpha: Byte; Color: Cardinal; Texture,Flags: Integer); stdcall;
  procedure Render4AEx   (X,Y,Width,Height,Angle, Frame: Single; Effect,Alpha: Byte; Color: Cardinal; Texture,Flags: Integer); stdcall;
  procedure Render4C     (X,Y,Width,Height,Angle: Single; Effect,Alpha: Byte; C1,C2,C3,C4: Cardinal; Texture,Flags: Integer); stdcall;

  procedure RenderTiles  (X,Y,Width,Height: Single; CX,CY: Integer; Angle: Single; Effect,Alpha:Byte; Color:Cardinal; Texture,Flags: Integer); stdcall;

  procedure DrawLine     (X1,Y1,X2,Y2: Single; Color: Cardinal; Alpha: Byte); stdcall;
  procedure DrawRect     (X,Y,Width,Height: Single; Color: Cardinal; Alpha: Byte); stdcall;
  procedure DrawCircle   (X,Y,Radius: Single; LineCount: Integer; Fill_It: Boolean; Color: Cardinal; Alpha: Byte); stdcall;

  procedure DrawText     (X,Y: Single; _String: string; FontSize,Texture,Xoff: Integer; Color: Cardinal; Flags: Byte);
  procedure DrawTextEx   (X,Y: Single; _String: string; FontSize,Texture,Xoff: Integer; C1,C2,C3,C4: Cardinal; Alpha: Byte; Angle: Single; Flags: Byte);

  procedure BeginBatch; stdcall;
  procedure EndBatch; stdcall;
end;
procedure CreateR2D(out ER2D: IR2D); stdcall; external EngDLL;
/// ////// ///


/// OTHER STUFF ///
function  K_DOWNA(KCode: byte): boolean; stdcall;
/// ////// ///

/// MOUSE STUFF ///
function  M_X: Integer; stdcall; external EngDLL;
function  M_Y: Integer; stdcall; external EngDLL;
function  M_Move: boolean; stdcall; external EngDLL;
procedure M_Hold; stdcall; external EngDLL;
function  M_Click(button: byte): boolean; stdcall; external EngDLL;
function  M_DClick(button: byte): boolean; stdcall; external EngDLL;
function  M_Down(button: byte): boolean; stdcall; external EngDLL;
function  M_Press(button: byte): boolean; stdcall; external EngDLL;
function  M_WheelUp: boolean; stdcall; external EngDLL;
function  M_WheelDown: boolean; stdcall; external EngDLL;
/// ////// ///

function BvsB(EngObj1,EngObj2:TEngObj): boolean;
function Mix : integer;
function Mix3 : integer;


/// CAMERA ///
type
TCamera = ^T2DCamera;
T2DCamera = record
  X, Y, Angle, Zoom : Single;
  Active : Boolean;
end;
/// ////// ///


/// SPRITE ENGINE (90%) ///
type
TSpriteClass = class
  SX, SY, SZ, SWidth, SHeight, SAngle : Single;
  SAlpha, SFX, SFlag : byte;
  SColor : Cardinal;
  SImage : integer;
 procedure Draw(Flag:byte; Z:integer); virtual; abstract;
 procedure Move; virtual; abstract;
end;

type
TImageSprite = class (TSpriteClass)
  Count : Integer;
  Sprites : array of TSpriteClass;
 constructor Create(X,Y,Z, Width,Height, Angle: Single; FX, Alpha: byte; Color: Cardinal; Image:Integer);
 procedure Draw(Flag:byte; Z:integer); override;
 procedure Move; override;
end;

type
TSpriteEngine = class
  Count : Integer;
  Sprites : array of TSpriteClass;
 constructor Create;
 procedure AddSprite(X,Y,Z, Width, Height,Angle: Single; FX, Alpha: byte; Color: Cardinal; Image:Integer);
 procedure DrawSprites;
 procedure MoveSprites;
end;


var
  Eng    : IJSMEng;
  R2D    : IR2D;
  Camera,
  AUXCam : TCamera;
  SE     : TSpriteEngine;

implementation


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

constructor TSpriteEngine.Create;
begin
inherited Create;
  Count:=0;
end;

procedure TSpriteEngine.AddSprite;
begin
  inc(Count);
  SetLength(Sprites,Count);
  Sprites[Count-1]:=TImageSprite.Create(X,Y,Z, Width,Height,Angle,FX, Alpha,Color, Image);
end;

procedure TSpriteEngine.DrawSprites;
var
  i : integer;
  z : byte;
begin
  for z:=10 downto 0 do
  for i:=0 to Count-1 do Sprites[i].Draw(Sprites[i].SFlag,Z);
end;

procedure TSpriteEngine.MoveSprites;
var
  i : integer;
begin
  for i:=0 to Count-1 do Sprites[i].Move;
end;


constructor TImageSprite.Create;
begin
  SX  := X;
  SY  := Y;
  SFX := FX;
  SWidth  := Width;
  SHeight := Height;
  SAngle  := Angle;
  SAlpha  := Alpha;
  SColor  := Color;
  SImage  := Image;
end;

procedure TImageSprite.Draw;
begin
for z:=10 downto 0 do
  R2D.Render4Ex(SX,SY, SWidth,SHeight, SAngle, SFX,SAlpha, SColor,SImage, Flag);
end;

procedure TImageSprite.Move;
begin
end;

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


function Mix:integer;
begin
 Result := Random(2);
 if (Result = 0) then result := -1;
end;

function Mix3:integer;
begin
 Result := Random(3);
 if (Result = 0) then Result := 0;
 if (Result = 1) then Result := -1;
 if (Result = 2) then Result := 1;
end;


function BvsB(EngObj1,EngObj2:TEngObj): boolean;
begin
if ( EngObj1.X + EngObj1.Width  >= EngObj2.X ) and ( EngObj1.X <= EngObj2.X + EngObj2.Width  ) and
   ( EngObj1.Y + EngObj1.Height >= EngObj2.Y ) and ( EngObj1.Y <= EngObj2.Y + EngObj2.Height ) then
  Result := True
else
  Result := False;
end;


function K_DOWNA(KCode: byte): boolean;
begin
  if GetAsyncKeyState(KCode) = 0 then Result := False
  else Result := True;
end;


initialization
  SE := TSpriteEngine.Create;
  GetMem(Pointer(AUXCam), SizeOf(T2DCamera));
  AUXCam^.Active := True;
  AUXCam^.X := 0;
  AUXCam^.Y := 0;
  AUXCam^.Angle := 0;
  Camera := AUXCam;
end.

