diff --git a/icon/rcbasic.ico b/icon/rcbasic.ico new file mode 100644 index 0000000..7dd551b Binary files /dev/null and b/icon/rcbasic.ico differ diff --git a/icon/rcbasic1.ico b/icon/rcbasic1.ico new file mode 100644 index 0000000..14823ce Binary files /dev/null and b/icon/rcbasic1.ico differ diff --git a/icon/rcbasic2.ico b/icon/rcbasic2.ico new file mode 100644 index 0000000..56ca0a9 Binary files /dev/null and b/icon/rcbasic2.ico differ diff --git a/rcbasic_build/cbc_spec.txt b/rcbasic_build/cbc_spec.txt new file mode 100644 index 0000000..0344d98 --- /dev/null +++ b/rcbasic_build/cbc_spec.txt @@ -0,0 +1,45 @@ +CBC VERSION 4 SPECIFICATION +-------------------------------- + +FIELD SIZE +----------------------------------- +RC4[XX] 5 bytes + + +//----TYPE HEADER----- +UTYPE_COUNT 8 bytes + + //----EACH TYPE------ + FIELD_COUNT 8 BYTES + + //----EACH FIELD---- + FIELD_TYPE 8 BYTES + * NUMBER = 0 + * STRING = 1 + * USER = 2 + FIELD_UTYPE 8 BYTES + FIELD_DIMENSIONS 8 BYTES + + +//----PROGRAM HEADER----- +N REGISTER COUNT 8 BYTES +S REGISTER COUNT 8 BYTES +U REGISTER COUNT 8 BYTES + +N STACK SIZE 8 BYTES +S STACK SIZE 8 BYTES +U STACK SIZE 8 BYTES + +LOOP STACK SIZE 8 BYTES + +NUM ID COUNT 8 BYTES +STRING ID COUNT 8 BYTES +USER ID COUNT 8 BYTES + +CODE SEGMENT SIZE 8 BYTES +DATA SEGMENT SIZE 8 BYTES + + +//----PROGRAM---- +CODE SEGMENT CODE SEGMENT SIZE +DATA SEGMENT DATA SEGMENT SIZE diff --git a/rcbasic_build/constants.h b/rcbasic_build/constants.h new file mode 100644 index 0000000..323aac1 --- /dev/null +++ b/rcbasic_build/constants.h @@ -0,0 +1,35 @@ +#ifndef CONSTANTS_H_INCLUDED +#define CONSTANTS_H_INCLUDED + +#include + +struct rc_user_constant +{ + string const_name; + vector const_tokens; +}; + +vector rc_constants; + +int create_constant(string c_name) +{ + for(int i = 0; i < rc_constants.size(); i++) + { + if(rc_constants[i].const_name.compare(c_name)==0) + return -1; //constant already exists + } + int const_id = rc_constants.size(); + + rc_user_constant c; + c.const_name = c_name; + + rc_constants.push_back(c); + return const_id; +} + +void add_const_token(int c_id, string c_token) +{ + rc_constants[c_id].const_tokens.push_back(c_token); +} + +#endif // CONSTANTS_H_INCLUDED diff --git a/rcbasic_build/embedded_functions.bas b/rcbasic_build/embedded_functions.bas new file mode 100644 index 0000000..22c6eee --- /dev/null +++ b/rcbasic_build/embedded_functions.bas @@ -0,0 +1,516 @@ +'StringFill +'Stack_Size_N +'Stack_Size_S +'Text I/O +sub FPrint(txt$) +function Input$(prompt$) +'Arrays +function ArrayDim(Byref id) +function StringArrayDim(Byref id$) +function NumberArrayDim(Byref id) +function ArraySize(Byref id, array_dim) +function StringArraySize(Byref id$, array_dim) +function NumberArraySize(Byref id, array_dim) +'Math +function Abs(n) +function ACos(n) +function AndBit(a,b) +function ASin(n) +function ATan(n) +function Bin$(n) +function CInt32(i) +function CInt64(i) +function Cos(n) +function Degrees(r) +function Exp(n) +function Frac(n) +function Hex$(n) +function HexVal(n$) +function Int(n) +function Log(n) +function Max(a, b) +function Min(a, b) +function OrBit(a, b) +function Radians(d) +function Randomize(n) +function Rand(n) +function Round(n) +function Sign(n) +function Sin(n) +function Sqrt(n) +function Tan(n) +function XOrBit(a, b) +'Strings +function Asc(c$) +function Chr$(n) +function Insert$(src$, tgt$, pos) +function InStr(src$, substr$) +function LCase$(src$) +function Left$(src$, n) +function Length(src$) +function Len(src$) +function LTrim$(src$) +function Mid$(src$, start, n) +function ReplaceSubstr$(src$, rpc$, pos) +function Replace$(src$, tgt$, rpc$) +function Reverse$(src$) +function Right$(src$, n) +function RTrim$(src$) +function StringFill$(src$, n) +function Str$(n) +function Str_F$(n) +function Str_S$(n) +function Tally(src$, substr$) +function Trim$(src$) +function UCase$(src$) +function Val(n$) +'Stacks +sub Stack_N(n) +sub Stack_S(n) +sub Push_N(n) +function Pop_N() +sub Push_S(s$) +function Pop_S$() +function Stack_Size_N() +function Stack_Size_S() +'File I/O +function FileOpen(stream, fileName$, mode) +sub FileClose(stream) +function ReadByte(stream) +sub WriteByte(stream, byte) +function ReadLine$(stream) +sub Write(stream, txt$) +sub WriteLine(stream, txt$) +sub CopyFile(src$, dst$) +function RemoveFile(fileName$) +function FileExists(fileName$) +function MoveFile(src$, dst$) +function RenameFile(src$, dst$) +function FileLength(fileName$) +function Tell(stream) +function Seek(stream, pos) +function EOF(stream) +function FreeFile() +'Directories +sub ChangeDir(p$) +function DirExists(p$) +function DirFirst$() +function Dir$() +function DirNext$() +function MakeDir(p$) +function RemoveDir(p$) +'Date and Time +function Date$() +function Easter$(year) +function Ticks() +function Time$() +function Timer() +sub Wait(m_sec) +'Window Management +sub WindowOpen(win, title$, x, y, w, h, flag, vsync) +sub WindowClose(win) +sub RaiseWindow(win) +sub Window(win) +sub Update() +sub Cls() +sub SetClearColor(c) +sub ShowWindow(win) +sub HideWindow(win) +sub SetWindowTitle(win, title$) +function WindowTitle$(win) +sub SetWindowPosition(win, x, y) +sub GetWindowPosition(win, byref x, byref y) +sub SetWindowSize(win, w, h) +sub GetWindowSize(win, byref w, byref h) +sub SetWindowMinSize(win, w, h) +sub GetWindowMinSize(win, byref w, byref h) +sub SetWindowMaxSize(win, w, h) +sub GetWindowMaxSize(win, byref w, byref h) +function WindowIsFullscreen(win) +function WindowIsVisible(win) +function WindowIsBordered(win) +function WindowIsResizable(win) +function WindowIsMinimized(win) +function WindowIsMaximized(win) +function WindowHasInputFocus(win) +function WindowHasMouseFocus(win) +sub SetWindowFullscreen(win, flag) +sub MaximizeWindow(win) +sub MinimizeWindow(win) +sub SetWindowBorder(win, flag) +sub WindowClip(slot, x, y, w, h) +function WindowExists(win) +function NumWindows() +function WindowEvent_Close(win) +function WindowEvent_Maximize(win) +function WindowEvent_Minimize(win) +function ActiveWindow() +function FPS() +sub SetWindowIcon(win, slot) +'Canvases +sub CanvasOpen(c_num, w, h, viewport_x, viewport_y, viewport_w, viewport_h, mode) +sub CanvasClose(c_num) +sub SetCanvasVisible(c_num, flag) +function CanvasIsVisible(c_num) +sub SetCanvasViewport(cnum, x, y, w, h) +sub GetCanvasViewport(c_num, byref x, byref y, byref w, byref h) +sub Canvas(c_num) +sub SetCanvasOffset(c_num, x, y) +sub GetCanvasOffset(c_num, byref x, byref y) +sub GetCanvasSize(c_num, byref w, byref h) +sub ClearCanvas() +sub SetCanvasAlpha(c_num, a) +function CanvasAlpha(c_num) +function SetCanvasBlendMode(c_num, blend_mode) +function CanvasBlendMode(c_num) +function SetCanvasColorMod(c_num, c) +function CanvasColorMod(c_num) +sub CopyCanvas(src, x, y, w, h, dst, dx, dy) +sub CloneCanvas(src, dst) +sub SetCanvasZ(c_num, z) +function CanvasZ(c_num) +sub CanvasClip(slot, x, y, w, h, flag) +function ActiveCanvas() +'Graphics Primitives +sub Box(x1, y1, x2, y2) +sub BoxFill(x1, y1, x2, y2) +sub Circle(x,y,radius) +sub CircleFill(x,y,radius) +sub Ellipse(x,y,rx,ry) +sub EllipseFill(x,y,rx,ry) +sub FloodFill(x,y) +function GetPixel(x,y) +sub SetColor(c) +sub Line(x1, y1, x2, y2) +sub Poly(n, byref x, byref y) +sub PolyFill(n, byref x, byref y) +sub Rect(x, y, w, h) +sub RectFill(x, y, w, h) +sub RoundRect(x, y, w, h, r) +sub RoundRectFill(x, y, w, h, r) +function RGB(r,g,b) +function RGBA(r,g,b,a) +sub PSet(x,y) +'Images +sub LoadImage(slot, img$) +sub LoadImage_Ex(slot, img$, colkey) +sub ImageFromBuffer(slot, w, h, byref buffer) +sub ImageFromBuffer_Ex(slot, w, h, byref buffer, colkey) +sub BufferFromImage(slot, byref buffer) +function ImageExists(slot) +sub ColorKey(slot, c) +sub CopyImage(src, dst) +sub DeleteImage(slot) +sub SetImageAlpha(slot, a) +function ImageAlpha(slot) +sub GetImageSize(slot, byref w, byref h) +function SetImageBlendMode(slot, blend_mode) +function ImageBlendMode(slot) +function SetImageColorMod(slot, c) +function ImageColorMod(slot) +sub DrawImage(slot, x, y) +sub DrawImage_Blit(slot, x, y, src_x, src_y, src_w, src_h) +sub DrawImage_Blit_Ex(slot, x, y, w, h, src_x, src_y, src_w, src_h) +sub DrawImage_Rotate(slot, x, y, angle) +sub DrawImage_Rotate_Ex(slot, x, y, src_x, src_y, src_w, src_h, angle) +sub DrawImage_Zoom(slot, x, y, zx, zy) +sub DrawImage_Zoom_Ex(slot, x, y, src_x, src_y, src_w, src_h, zx, zy) +sub DrawImage_Rotozoom(slot, x, y, angle, zx, zy) +sub DrawImage_Rotozoom_Ex(slot, x, y, src_x, src_y, src_w, src_h, angle, zx, zy) +sub DrawImage_Flip(slot, x, y, h, v) +sub DrawImage_Flip_Ex(slot, x, y, src_x, src_y, src_w, src_h, h, v) +'Keyboard and Mouse +function InKey() +function Key(key_code) +function WaitKey() +sub HideMouse() +sub ShowMouse() +function MouseIsVisible() +sub GetMouse(byref x, byref y, byref mb1, byref mb2, byref mb3) +function MouseX() +function MouseY() +function MouseButton(mb) +sub GetMouseWheel(byref x_axis, byref y_axis) +function MouseWheelX() +function MouseWheelY() +'Sound and Music +sub SoundFromBuffer(slot, byref buffer, buffer_size, vol) +sub LoadSound(slot, snd_file$) +sub LoadMusic(music_file$) +sub PlaySound(slot, channel, loops) +sub PlaySoundTimed(slot, channel, loops, ms) +sub PlayMusic(mLoops) +sub PauseSound(channel) +sub ResumeSound(channel) +sub PauseMusic() +sub ResumeMusic() +sub DeleteSound(slot) +sub DeleteMusic() +sub FadeMusicIn(fade_time, loops) +sub FadeMusicOut(fade_time) +function MusicExists() +sub SetMusicVolume(vol) +function MusicVolume() +sub SetMusicPosition(pos) +function MusicPosition() +sub RewindMusic() +sub SetSoundChannels(max_channels) +function NumSoundChannels() +function SoundIsEnabled() +function SoundExists(slot) +sub SetChannelVolume(channel, vol) +function ChannelVolume(channel) +sub SetSoundVolume(slot, vol) +function SoundVolume(slot) +sub StopMusic() +sub StopSound(channel) +function SetChannelPanning(channel, left_value, right_value) +function SetChannelDistance(channel, dist_value) +function ChannelIsPlaying(channel) +function ChannelIsPaused(channel) +'Joysticks +function NumJoysticks() +function NumJoyAxes(joy_num) +function NumJoyButtons(joy_num) +function NumJoyHats(joy_num) +function NumJoyTrackBalls(joy_num) +function JoyAxis(joy_num, joy_axis) +function JoyButton(joy_num, joy_button) +function JoyHat(joy_num, joy_hat) +sub GetJoyTrackBall(joy_num, ball, byref dx, byref dy) +function JoyName$(joy_num) +function JoystickIsConnected(joy_num) +'Screen Console +sub GetCursor(byref x, byref y) +sub PrintS(txt$) +function InputS$(prompt$) +function ZoneInputS$(x, y, w, h) +sub Locate(x, y) +'Text Editing +sub ReadInput_Start() +sub ReadInput_Stop() +function ReadInput_Text$() +sub ReadInput_SetText(txt$) +sub ReadInput_ToggleBackspace(flag) +'Text Drawing +sub LoadFont(slot, fnt_file$, size) +sub DeleteFont(slot) +function FontIsLoaded(slot) +sub Font(slot) +sub SetFontStyle(slot, style) +sub DrawText(txt$, x, y) +sub DrawText_Shaded(txt$, x, y, fg_color, bg_color) +sub DrawText_Blended(txt$, x, y) +sub RenderText(slot, txt$) +sub GetTextSize(slot, txt$, byref w, byref h) +'Touch Events +function TouchPressure() +sub GetTouch(byref status, byref x, byref y, byref dx, byref dy) +sub GetMultiTouch(byref status, byref x, byref y, byref fingers, byref dist, byref theta) +sub GetTouchFinger(finger, byref x, byref y, byref pressure) +function NumFingers() +'Networking +function CheckSockets(timeout_ms) +function TCP_SocketReady(socket) +function UDP_SocketReady(socket) +function TCP_SocketOpen(socket, host$, port) +sub TCP_SocketClose(socket) +function TCP_RemoteHost(socket) +function TCP_RemotePort(socket) +function TCP_GetData(socket, ByRef sData$, numBytes) +sub TCP_SendData(socket, sData$) +function TCP_AcceptSocket(server, client) +function UDP_SocketOpen(socket, port) +function UDP_SocketClose(socket) +function UDP_GetData(socket, byref sData$, byref host$, byref port) +function UDP_Length() +function UDP_MaxLength() +function UDP_RemoteHost$(socket) +function UDP_RemotePort(socket) +sub UDP_SendData(socket, sData$, host$, port) +'Video Playback +sub LoadVideo(vid$) +sub PlayVideo(vLoops) +sub PauseVideo() +sub StopVideo() +sub SetVideoPosition(pos) +sub ResumeVideo() +function VideoPosition() +sub DeleteVideo() +function VideoIsPlaying() +function VideoEnd() +sub GetVideoStats(vFile$, byref vLen, byref vfps, byref frame_w, byref frame_h) +sub SetVideoDrawRect(x, y, w, h) +sub GetVideoDrawRect(byref x, byref y, byref w, byref h) +sub GetVideoSize(byref w, byref h) +function VideoExists() +sub SetVideoAlpha(a) +'Operating System +function System(cmd$) +function OS$() +function Command$(arg) +function NumCommands() +function Env$(v$) +sub SetEnv(var$, value$, overwrite) +function PrefPath$(org_name$, app_name$) +function Android_GetExternalStoragePath$() +function Android_GetExternalStorageState() +function Android_GetInternalStoragePath$() +function Android_JNI_Message$(arg$) +function Runtime_Utility_Message$(arg$) +'Clipboard +function ClipboardText$() +sub SetClipboardText(txt$) +function HasClipboardText() + +'v3.12 +Sub GetDesktopDisplayMode(index, ByRef w, ByRef h, ByRef freq) +Sub DrawImage_Transform(slot, x, y, w, h, src_x, src_y, src_w, src_h, angle, center_x, center_y, flip_h, flip_v) +Sub GetPowerInfo(ByRef status, ByRef secs, ByRef pct) +Function SystemRam() +Function SetRenderScaleQuality(n) +Function EvalJS$(js_code$) 'Only useable in Emscripten +Function GetRenderScaleQuality() + +'v3.14 +sub GetGlobalMouse(ByRef x, ByRef y, ByRef mb1, ByRef mb2, ByRef mb3) +function GlobalMouseX() +function GlobalMouseY() +sub GetAccel(accel_num, ByRef x, ByRef y, ByRef z) +function AccelName$(accel_num) +function NumAccels() +sub GetGyro(gyro_num, ByRef x, ByRef y, ByRef z) +function GyroName$(gyro_num) +function NumGyros() +sub JoyRumblePlay(joy_num, strength, duration) +sub JoyRumbleStop(joy_num) +function JoystickIsHaptic(joy_num) +function WriteByteBuffer(stream, ByRef buf, buf_size) +function ReadByteBuffer(stream, ByRef buf, buf_size) +function WindowEvent_Resize(win) +sub SetWindowAutoClose( win, exit_on_close ) +sub SetWindowResizable(win, flag) 'new +function SystemReturnStdOut$(cmd$) 'new +function WindowMode(visible, fullscreen, resizable, borderless, highDPI) +function WindowFlags(win) +sub RestoreWindow(win) +sub UpdateAllWindows() 'new +function QueryAudioSpec(ByRef freq, ByRef format, ByRef channels) 'new + +'v3.15 +function MusicIsPlaying() + +'v3.19 +function DrawGeometry(slot, num_vertices, ByRef vertices, num_indices, ByRef Indices) + +'v3.20 +function Size(s$) +function BufferFromString(s$, ByRef buffer) +function StringFromBuffer$(ByRef buffer, buffer_size) +sub GrabInput(flag) +function GrabbedWindow() +sub WarpMouse(x, y) +sub WarpMouseGlobal(x, y) +sub SetMouseZone(x, y, w, h) +sub ClearMouseZone() +sub SetWindowAlwaysOnTop(win, flag) +sub SetMouseRelative(flag) +sub SetWindowVSync(win, flag) +function OpenURL(url$) +function APIVersion$() +function FlashWindow(win) +function MessageBox(title$, msg$) +sub NumberArrayCopy(ByRef src, ByRef dst) +sub StringArrayCopy(ByRef src$, ByRef dst$) +sub ArrayCopy(ByRef src, ByRef dst) +sub NumberArrayFill(ByRef src, fdata) +sub StringArrayFill(ByRef src$, fdata$) +sub ArrayFill(ByRef src, fdata) +function Runtime$() + +'More v3.20 (Matrices and Parrallism) +sub DimMatrix(m, m_rows, m_cols, preserve_flag) +function AddMatrix(mA, mB, mC) +function AugmentMatrix (mA, mB, mC) +sub CopyMatrix(mA, mB) +function InsertMatrixColumns(mA, c, num_cols) +function InsertMatrixRows(mA, r, num_rows) +function MultiplyMatrix (mA, mB, mC) +function CubeMatrix(mA, mB) +function DeleteMatrixColumns(mA, c, num_cols) +function DeleteMatrixRows(mA, r, num_rows) +sub ClearMatrix(mA) +function ClearMatrixColumns (mA, c, num_cols) +function ClearMatrixRows(mA, r, num_rows) +sub FillMatrix(mA, v) +function FillMatrixColumns(mA, c, num_cols, v) +function FillMatrixRows(mA, r, num_rows, v) +function CopyMatrixColumns(mA, mB, c, num_cols) +function CopyMatrixRows (mA, mB, r, num_rows) +sub IdentityMatrix(mA, n) +function SolveMatrix(mA, mB, mC) +function IsEqualMatrix(mA, mB, tolerance) +function Determinant(mA) +function AdjointMatrix(mA, mB) +function InvertMatrix(mA, mB) +sub MatrixFromBuffer(mA, r, c, ByRef buffer) +sub GetMatrix(ByRef buffer, mA) +sub RandomizeMatrix(mA, vmin, vmax) +function MatrixValue(mA, r, c) +sub SetMatrixValue(mA, r, c, v) +sub ScalarMatrix (mA, mB, s_value) +function ScalarMatrixColumns(mA, mB, c, num_cols, s_value) +function ScalarMatrixRows(mA, mB, r, num_rows, s_value) +function SquareMatrix(mA, mB) +sub SubMatrix(mA, r, c) +function SubtractMatrix (mA, mB, mC) +sub SwapMatrix(mA, mB) +function SwapMatrixColumn(mA, C1, C2) +function SwapMatrixRow(mA, R1, R2) +function TransposeMatrix(mA, mB) +function UnAugmentMatrix(mA, mB, mC) +sub ZeroMatrix(mA) + +sub GetMatrixSize(mA, ByRef r, ByRef c) +function SetMatrixProcess(p_num) 'Set to -1 for main thread + + +'ERROR_FLAG - MATRIX_ON_ERROR_STOP, MATRIX_ON_ERROR_WAIT, MATRIX_ON_ERROR_CONTINUE +function ProcessOpen(p_num) 'stops and locks mutex, and clears queue before changing mode +sub SetProcessErrorMode(p_num, error_mode) +function ProcessError(p_num) +sub ProcessWait(p_num) 'waits for all calculations to complete and lock matrix mutex +sub ProcessWaitAll() 'waits for all process to finish +sub ProcessContinue(p_num) 'unlock mutex +sub ProcessStop(p_num) 'stops after current calculation its working on and lock mutex +sub ProcessClear(p_num) 'locks mutex and clears matrix queue +function ProcessClose(p_num) +function ProcessErrorMode(p_num) +sub ProcessSleep(p_num, msec) +function ProcessExists(p_num) +sub ProcessStopAll() +sub ProcessContinueAll() +function ProcessQueueSize(p_num) + +function NumCPUs() + +'v3.21 +sub GetProjectionGeometry(cam_dist, mA, f_vertex_count, ByRef columns, ByRef uv, graph_offset_x, graph_offset_y, v_color, ByRef vertex_count, ByRef vertex2D, ByRef index_count, ByRef index, ByRef clip_dist, ByRef min_x, ByRef min_y, ByRef max_x, ByRef max_y) +function CalculateFaceZ(cam_dist, graph_offset_x, graph_offset_y, view_w, view_h, view_depth, mA, f_vertex_count, ByRef columns, ByRef face_min_z, ByRef face_max_z, ByRef z_avg) +function SetChannelSpacePosition(channel, angle, distance) +function SaveBMP(img, file$) +function SavePNG(img, file$) +function SaveJPG(img, file$) +Function GetLineIntersection(p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y, ByRef i_x, ByRef i_y) +Function Interpolate(min_a, max_a, mid_a, min_b, max_b) +Function ATan2(y, x) +function PointInQuad(x, y, x1, y1, x2, y2, x3, y3, x4, y4) +function PointInTri(x, y, x1, y1, x2, y2, x3, y3) +Function Distance2D(x1, y1, x2, y2) +Function Distance3D(x1, y1, z1, x2, y2, z2) +function GetCircleLineIntersection(circle_x, circle_y, radius, x1, y1, x2, y2, ByRef ix1, ByRef iy1, ByRef ix2, ByRef iy2) +function GetLinePlaneIntersection(ByRef line_point, ByRef line_direction, ByRef plane_point_1, ByRef plane_point_2, ByRef plane_point_3, ByRef intersection) +sub IncrementMatrixRows(mA, mB, r, num_rows, value) +sub IncrementMatrixColumns(mA, mB, c, num_cols, value) +sub JoinMatrixRows(mA, mB, mC) +sub JoinMatrixColumns(mA, mB, mC) diff --git a/rcbasic_build/env_resolve.h b/rcbasic_build/env_resolve.h new file mode 100644 index 0000000..1938dc1 --- /dev/null +++ b/rcbasic_build/env_resolve.h @@ -0,0 +1,64 @@ +#ifndef ENV_RESOLVE_H_INCLUDED +#define ENV_RESOLVE_H_INCLUDED + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + #define RC_WINDOWS +#elif __APPLE__ + #define RC_MAC +#elif __linux__ + #define RC_LINUX +#endif + +#ifdef RC_WINDOWS +#include +#else +#include +#endif // RC_WINDOWS + +string rc_intern_env(string v) +{ + #ifdef RC_WINDOWS + char * val = new char[32767]; + int n = GetEnvironmentVariable(v.c_str(), val, 32767); + string rtn = ""; + if (n>0) + rtn = (string)val; + delete val; + return rtn; + #else + char * c = getenv(v.c_str()); + if(c != NULL) + return (string) c; + return ""; + #endif +} + +string resolveEnvironmentVariables(string sdata) +{ + string sdata_out = ""; + for(int i = 0; i < sdata.length(); i++) + { + if(sdata.substr(i, 2).compare("${")==0) + { + int end_index = sdata.substr(i+2).find_first_of("}"); + if(end_index == string::npos) + { + cout << "Error: Missing closing } in environment variable" << endl; + return sdata_out; + } + string env_var = sdata.substr(i+2).substr(0, end_index); + //cout << "env_var is " << env_var << endl; + string env_value = rc_intern_env(env_var); + sdata_out += env_value; + i = (i+2) + end_index; + continue; + } + else + { + sdata_out += sdata.substr(i, 1); + } + } + return sdata_out; +} + +#endif // ENV_RESOLVE_H_INCLUDED diff --git a/rcbasic_build/file_directory.h b/rcbasic_build/file_directory.h new file mode 100644 index 0000000..579956d --- /dev/null +++ b/rcbasic_build/file_directory.h @@ -0,0 +1,231 @@ +#ifndef FILE_DIRECTORY_H_INCLUDED +#define FILE_DIRECTORY_H_INCLUDED + + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + #define RC_WINDOWS +#elif __APPLE__ + #define RC_MAC +#elif __linux__ + #define RC_LINUX +#endif + + +#include //file system stuff +#include //file system stuff +#include //file system stuff +#include +#include + + +#ifdef RC_MAC +#define RC_GETCWD +#include +#endif + +#ifdef RC_WINDOWS +#include +#include +#include +#endif // RC_WINDOWS + + +#ifndef RC_WINDOWS + +struct dirent *rc_entry; +DIR *rc_dir; +string rc_dir_path = ""; + +#else + +struct dirent *rc_entry; +string rc_dir; +string rc_dir_path = ""; +HANDLE hfind; + +#endif // RC_LINUX + + +#ifndef RC_WINDOWS + + + #ifdef RC_LINUX + inline int rc_intern_dirChange(string ch_path) + { + if(chdir(ch_path.c_str())!=0) + { + cout << "Error: Could not change directory\n"; + return 2; + } + rc_dir_path = get_current_dir_name(); + return 0; + } + #endif // RC_LINUX + +inline bool rc_intern_dirExist(string d_path) +{ + struct stat info; + + if(stat( d_path.c_str(), &info ) != 0) + return false; + else if(info.st_mode & S_IFDIR) + return true; + else + return false; +} + + #ifdef RC_GETCWD + string getcwd_str() + { + char *buffer = new char[MAXPATHLEN]; + getcwd(buffer,MAXPATHLEN); + if(buffer != NULL) + { + string ret(buffer); + delete[] buffer; + return ret; + } + else + { + return string(); + } + } + + + inline int rc_intern_dirChange(string ch_path) + { + if(chdir(ch_path.c_str())!=0) + { + cout << "Error: Could not change directory\n"; + return 2; + } + rc_dir_path = getcwd_str(); + return 0; + } + + inline string rc_intern_dir() + { + string d = getcwd_str(); + //__android_log_print(ANDROID_LOG_ERROR, "RC_DEBUG_DIR", "%s", SDL_GetPrefPath("rcbasic","lucky")); + if(d.compare("")==0) + { + //cout << "Could not get current directory" << endl; + return ""; + } + rc_dir_path = d; + return d; + } + + #else + + inline string rc_intern_dir() + { + string d = get_current_dir_name(); + if(d.compare("")==0) + { + cout << "Could not get current directory" << endl; + return ""; + } + rc_dir_path = d; + return d; + } + + #endif // RC_ANDROID + + +#else + +inline int rc_intern_dirChange(string dpath) +{ + if(SetCurrentDirectory(dpath.c_str())==0) + { + cout << "Error: Could not change directory\n"; + return 2; + } + + DWORD nBufferLength = MAX_PATH; + char szCurrentDirectory[MAX_PATH + 1]; + GetCurrentDirectory(nBufferLength, szCurrentDirectory); + szCurrentDirectory[MAX_PATH] = '\0'; + + rc_dir_path = (string)szCurrentDirectory; + return 0; +} + +bool dirExists(const std::string& dirName_in) +{ + DWORD ftyp = GetFileAttributesA(dirName_in.c_str()); + if (ftyp == INVALID_FILE_ATTRIBUTES) + return false; //something is wrong with your path! + + if (ftyp & FILE_ATTRIBUTE_DIRECTORY) + return true; // this is a directory! + + return false; // this is not a directory! +} + +inline int rc_intern_dirExist(string dpath) +{ + return dirExists(dpath); +} + +HANDLE hFind; +WIN32_FIND_DATA ffd; + +inline string rc_intern_dir() +{ + TCHAR buf[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, buf); + string d = buf; + + if(d.compare("")==0) + { + cout << "Could not get current directory" << endl; + return ""; + } + return d; +} + +#endif // RC_WINDOWS + + +string rc_absFilePath(string file_path) +{ + //cout << "file_path: " << file_path << endl; + string cwd = rc_intern_dir(); + int start_index = 0; + string::size_type bs_index = file_path.find_last_of("\\"); + string::size_type fs_index = file_path.find_last_of("/"); + int end_index = 0; + + if(bs_index==string::npos && fs_index==string::npos) + { + #ifdef RC_WINDOWS + return cwd + "\\" + file_path; + #else + return cwd + "/" + file_path; + #endif // RC_WINDOWS + } + + end_index = ( (bs_index > fs_index || fs_index == string::npos) && bs_index != string::npos) ? bs_index : fs_index; + + + if(rc_intern_dirExist(file_path.substr(0, end_index))) + { + rc_intern_dirChange(file_path.substr(0, end_index)); + + #ifdef RC_WINDOWS + string abs_file_path = rc_intern_dir() + "\\" + file_path.substr(end_index+1); + #else + string abs_file_path = rc_intern_dir() + "/" + file_path.substr(end_index+1); + #endif // RC_WINDOWS + + rc_intern_dirChange(cwd); + return abs_file_path; + } + + return file_path; +} + + +#endif // FILE_DIRECTORY_H_INCLUDED diff --git a/rcbasic_build/identifier.h b/rcbasic_build/identifier.h new file mode 100644 index 0000000..8fb8c83 --- /dev/null +++ b/rcbasic_build/identifier.h @@ -0,0 +1,1248 @@ +#ifndef IDENTIFIER_H_INCLUDED +#define IDENTIFIER_H_INCLUDED + +#include +#include +#include "rc_global.h" +#include "rc_utility.h" +#include "rc_debug.h" +//identifier structure information + +//identifier types +#define ID_TYPE_NUM 1 +#define ID_TYPE_STR 2 +#define ID_TYPE_FN_NUM 3 +#define ID_TYPE_FN_STR 4 +#define ID_TYPE_BYREF_NUM 5 +#define ID_TYPE_BYREF_STR 6 +#define ID_TYPE_ARR_NUM 7 +#define ID_TYPE_ARR_STR 8 +#define ID_TYPE_SUB 9 +#define ID_TYPE_USER 10 +#define ID_TYPE_FN_USER 11 +#define ID_TYPE_BYREF_USER 12 +#define ID_TYPE_USER_NUM 13 +#define ID_TYPE_USER_STR 14 +#define ID_TYPE_USER_NUM_ARRAY 15 +#define ID_TYPE_USER_STR_ARRAY 16 + +#define ID_TYPE_USER_ALL(id_index) ( id[id_index].type == ID_TYPE_USER || id[id_index].type == ID_TYPE_BYREF_USER || id[id_index].type == ID_TYPE_USER_NUM || id[id_index].type == ID_TYPE_USER_STR || id[id_index].type == ID_TYPE_USER_NUM_ARRAY || id[id_index].type == ID_TYPE_USER_STR_ARRAY ) + +#define BLOCK_STATE_MAIN 0 +#define BLOCK_STATE_TYPE 1 +#define BLOCK_STATE_FUNCTION 2 +#define BLOCK_STATE_SUB 3 +#define BLOCK_STATE_FOR 4 +#define BLOCK_STATE_WHILE 5 +#define BLOCK_STATE_DO 6 +#define BLOCK_STATE_IF 7 +#define BLOCK_STATE_SELECT 8 + +using namespace std; + +string current_scope = "main"; +int current_block_state = BLOCK_STATE_MAIN; //This hold different states depending on the type of block the program is currently in ie. type, function, sub, for, while, do, if, select +int current_type_index = 0; +int current_fn_index = 0; +bool isInFunctionScope = false; +int current_fn_id_count = 0; + +uint64_t current_for_index = 0; +uint64_t current_while_index = 0; +uint64_t current_do_index = 0; + +uint64_t current_if_index = 0; +uint64_t current_select_index = 0; + +stack block_state; +stack for_end; +stack for_counter; +stack do_end; +stack while_end; + +bool isFunctionArg_flag = false; + +bool enable_presets = true; + +struct if_data +{ + uint64_t index = 0; + uint64_t condition = 0; + bool else_set = false; +}; + +struct select_data +{ + int case_type = ID_TYPE_NUM; + int index = 0; + int case_index = 0; + bool default_set = false; + bool case_set = false; +}; + +stack if_block; +stack select_block; + +//array dimension structure +struct user_array_dim +{ + int dim_size[3]; +}; + + +//user defined type structure +struct rc_type_description +{ + uint32_t nidCount; + uint32_t nidDim; + uint32_t nidDimSize[3]; + + uint32_t sidCount; + uint32_t sidDim; + uint32_t sidDimSize[3]; + + uint32_t uidCount; + uint32_t uidDim; + uint32_t uidDimSize[3]; + uint32_t uidTypeIndex; +}; + +struct user_type +{ + string name; //name of the type + int num_members; //number of members + vector member_name; //name of the members in the type + vector member_type; //type of each member + vector member_vec_pos; //the vector position for each member + int nidCount = 0; + int sidCount = 0; + int uidCount = 0; + vector member_utype_index; + vector member_dim_count; //number of dimensions for each member + vector member_dim; //size of each dimension in an array +}; + +struct fid_vector_entry +{ + string vec_str; + int type; +}; + +//identifier structure +struct identifier +{ + string name; //variable or function name + string scope; //the scope this identifier was created in + int type; //the identifier type, it will be one of the types above + int type_index; //if the identifier is a user_type, then this will be the index of the type within the utype vector + int num_args; //number of arguments in a function or number of dimensions in an array + uint64_t dim_size[3]; //size of each dimension in an array, up to 3 dimensions are supported + vector fn_arg; //function argument name + vector fn_reg; + vector fn_arg_vec; + vector fn_arg_type; //function argument type + vector fn_arg_utype; + uint64_t vec_pos; //position in num, string, or user type vector for runtime + bool isBuiltin = false; + uint64_t vmFunctionIndex = 0; + bool isArrayArg = false; + vector fn_var; + bool isChild = false; + int parent_index = -1; +}; + + +uint64_t current_vmFunction_index = 0; + +vector utype; +vector id; + +int num_id_count = 0; +int str_id_count = 0; +int usr_id_count = 0; + +int fn_numCount = 0; +int fn_strCount = 0; +int fn_usrCount = 0; +int fn_byref_numCount = 0; +int fn_byref_strCount = 0; +int fn_byref_usrCount = 0; + +int max_fn_numCount = 0; +int max_fn_strCount = 0; +int max_fn_usrCount = 0; +int max_fn_byref_numCount = 0; +int max_fn_byref_strCount = 0; +int max_fn_byref_usrCount = 0; + +bool idExists(string id_name) +{ + id_name = StringToUpper(id_name); + for(int i = 0; i < id.size(); i++) + { + if(id_name.compare(StringToUpper(id[i].name))==0) + return true; + } + return false; +} + +bool matchCurrentScope(string id_scope, string check_scope = "") +{ + string tmp_current_scope = ""; + string tmp_id_scope = ""; + + int cs_i = 0; + int id_i = 0; + + if(check_scope.compare("")==0) + check_scope = current_scope; + + while(true) + { + tmp_current_scope = ""; + tmp_id_scope = ""; + for(; cs_i < check_scope.length(); cs_i++) + { + if(check_scope.substr(cs_i,1).compare(".")==0) + { + cs_i++; + break; + } + tmp_current_scope += check_scope.substr(cs_i,1); + } + for(; id_i < id_scope.length(); id_i++) + { + if(id_scope.substr(id_i,1).compare(".")==0) + { + id_i++; + break; + } + tmp_id_scope += id_scope.substr(id_i,1); + } + if(tmp_current_scope.compare(tmp_id_scope)!=0) + { + return false; + } + if(id_i == id_scope.length()) + { + //cout << "SCOPE_MATCH: " << tmp_current_scope << " ~ " << tmp_id_scope << endl; + //cout << "INFO: " << id_scope << " ~ " << check_scope << endl; + return true; + } + } + return false; +} + +bool idExistsInScope2(string id_name) +{ + id_name = StringToLower(id_name); + int cs_start = 0; + int cs_length = 0; + bool match = true; + string id_scope = ""; + for(int i = 0; i < id.size(); i++) + { + if(id_name.compare(StringToLower(id[i].name) )==0) + { + //cout << endl; + //cout << "ID found in: " << id[i].scope << endl; + //cout << "Current Scope: " << current_scope << endl; + //cout << endl; + //id has to exist in or above current scope + if(current_scope.length() < id[i].scope.length()) + { + continue; + } + + id_scope = ""; + cs_start = 0; + cs_length = 0; + match = true; + + //if(current_scope.find(id[i].scope)==0) + if(matchCurrentScope(id[i].scope)) + { + //cout << id_name << " -> " << id[i].name << " : " << id[i].scope << " : " << current_scope << endl; + return true; + } + } + } + return false; +} + +bool idExistsInScope(string id_name) +{ + bool exists = idExistsInScope2(id_name); + if(!exists) + { + if(id_name.substr(id_name.length()-1,1).compare("$")==0) + exists = idExistsInScope2(id_name.substr(0, id_name.length()-1)); + else + exists = idExistsInScope2(id_name + "$"); + } + return exists; +} + +void output_vars() +{ + for(int i = 0; i < id.size(); i++) + { + cout << endl; + cout << "id: " << id[i].name << " : " << id[i].vec_pos << endl; + cout << "type: " << id[i].type << endl; + if(id[i].type == ID_TYPE_USER) + cout << "type_id: " << utype[id[i].type_index].name << endl; + cout << "scope: " << id[i].scope << endl; + cout << "dim: " << id[i].num_args << endl; + for(int n = 0; n < id[i].num_args; n++) + cout << "dim[" << n << "] = " << id[i].dim_size[n] << endl; + } + cout << endl; +} + +int getUType(string utype_name) +{ + utype_name = StringToLower(utype_name); + for(int i = 0; i < utype.size(); i++) + { + //cout << "TYPE[" << i << "] = " << utype[i].name << endl; + if(utype_name.compare(utype[i].name)==0) + { + return i; + } + } + rc_setError(utype_name + " does not name a type"); + return -1; +} + +bool create_type(string utype_name) +{ + utype_name = StringToLower(utype_name); + if(isKeyWord(utype_name) || idExistsInScope(utype_name)) + { + rc_setError(utype_name + " is not a valid identifier"); + return false; + } + else if(getUType(utype_name)>=0) + { + rc_setError(utype_name + " already exists"); + return false; + } + current_type_index = utype.size(); + //cout << "current type_index = " << current_type_index << endl; + user_type ut; + ut.name = utype_name; + ut.num_members = 0; + utype.push_back(ut); + return true; +} + +bool memberExists(string member_name) +{ + for(int i = 0; i < utype[current_type_index].num_members; i++) + { + if(utype[current_type_index].member_name[i].compare(member_name)==0) + return true; + } + return false; +} + +bool add_type_member(string member_name, int member_type, string member_utype_name, int member_dim_count, string dim1 = "n0", string dim2 = "n0", string dim3 = "n0") +{ + int m_utype_index = member_utype_name.compare("")!=0 ? getUType(member_utype_name) : -1; + if(m_utype_index == current_type_index) + { + //cout << "you canno do is" << endl; + rc_setError("Cannot create member of type from within itself"); + return false; + } + //cout << "utype index = " << current_type_index << endl; + int utype_index = current_type_index; + int utype_current_member = utype[utype_index].num_members; + member_name = StringToLower(member_name); + utype[utype_index].member_name.push_back(member_name); + + string dim_mem_type = ""; + + switch(member_type) + { + case ID_TYPE_NUM: + dim_mem_type = "!0 !" + rc_intToString(utype_current_member); + utype[utype_index].member_type.push_back(ID_TYPE_USER_NUM); + utype[utype_index].member_vec_pos.push_back(utype[utype_index].nidCount); + utype[utype_index].nidCount++; + break; + case ID_TYPE_ARR_NUM: + dim_mem_type = "!0 !" + rc_intToString(utype_current_member); + utype[utype_index].member_type.push_back(ID_TYPE_USER_NUM_ARRAY); + utype[utype_index].member_vec_pos.push_back(utype[utype_index].nidCount); + utype[utype_index].nidCount++; + break; + case ID_TYPE_STR: + dim_mem_type = "!1 !" + rc_intToString(utype_current_member); + utype[utype_index].member_type.push_back(ID_TYPE_USER_STR); + utype[utype_index].member_vec_pos.push_back(utype[utype_index].sidCount); + utype[utype_index].sidCount++; + break; + case ID_TYPE_ARR_STR: + dim_mem_type = "!1 !" + rc_intToString(utype_current_member); + utype[utype_index].member_type.push_back(ID_TYPE_USER_STR_ARRAY); + utype[utype_index].member_vec_pos.push_back(utype[utype_index].sidCount); + utype[utype_index].sidCount++; + break; + case ID_TYPE_USER: + dim_mem_type = "!2 !" + rc_intToString(utype_current_member); + utype[utype_index].member_type.push_back(ID_TYPE_USER); + utype[utype_index].member_vec_pos.push_back(utype[utype_index].uidCount); + utype[utype_index].uidCount++; + break; + default: + rc_setError("Invalid member type in type definition"); + return false; + break; + } + + utype[utype_index].member_dim_count.push_back(member_dim_count); + utype[utype_index].member_utype_index.push_back(m_utype_index); + + dim1 = dim1.compare("")==0 ? "n0" : dim1; + dim2 = dim2.compare("")==0 ? "n0" : dim2; + dim3 = dim3.compare("")==0 ? "n0" : dim3; + + vm_asm.push_back("dim_tfield !" + rc_intToString(utype_index) + " " + dim_mem_type + " !" + + rc_intToString(member_dim_count) + " " + + dim1 + " " + dim2 + " " + dim3); + + //NOTE: user_array_dim is no longer used + user_array_dim d; + //d.dim_size[0] = dim1; + //d.dim_size[1] = dim2; + //d.dim_size[2] = dim3; + utype[utype_index].member_dim.push_back(d); + //cout << member_name << " has " << member_dim_count << " dimensions" << endl; + //utype[utype_index].member_dim[utype_current_member].dim_size[1] = dim2; + //utype[utype_index].member_dim[utype_current_member].dim_size[2] = dim3; + utype[utype_index].num_members++; + return true; +} + +//return the index of the id name or -1 on failure +int getIDInScope_ByIndex_TypeMatch(string id_name, string check_scope="") +{ + id_name = StringToLower(id_name); + int cs_start = 0; + int cs_length = 0; + bool match = true; + string id_scope = ""; + if(check_scope.compare("")==0) + check_scope = current_scope; + int scope_match = 0; + int tmp_match = 0; + int id_match = -1; + check_scope = StringToLower(check_scope); + //cout << "CHECK SCOPE = " << check_scope << endl; + for(int i = 0; i < id.size(); i++) + { + if(id[i].scope.compare(check_scope)==0) + { + //cout << id_name << " ~ " << id[i].name << endl; + if(id_name.compare(id[i].name)==0) + return i; + } + } + return id_match; +} + +//return the index of the id name or -1 on failure +int getIDInScope_ByIndex2(string id_name, string check_scope="") +{ + id_name = StringToLower(id_name); + int cs_start = 0; + int cs_length = 0; + bool match = true; + string id_scope = ""; + if(check_scope.compare("")==0) + check_scope = current_scope; + int scope_match = 0; + int tmp_match = 0; + int id_match = -1; + for(int i = 0; i < id.size(); i++) + { + //if(StringToLower(id_name).compare("tst")==0 && StringToLower(id[i].name.substr(0,1)).compare("t")==0) + // cout << "CMP: " << id_name << " to " << id[i].name << endl; + if(id_name.compare(StringToLower(id[i].name))==0) + { + //cout << endl; + //cout << "ID_NAME = " << id[i].name << endl; + //cout << "ID found in: " << id[i].scope << endl; + //cout << "Current Scope: " << check_scope << endl; + //cout << endl; + //id has to exist in or above current scope + if(check_scope.length() < id[i].scope.length()) + { + //cout << "SCOPE CHECK: " << check_scope.length() << " <> " << id[i].scope.length() << endl; + continue; + } + + //if(current_scope.find(id[i].scope)==0) + if(matchCurrentScope(id[i].scope, check_scope)) + { + //cout << "FOUND MATCH FOR [" << id[i].name << "] : " << id[i].vec_pos << " ; " << id[i].scope << " : t=" << id[i].type << endl << endl; + return i; + } + } + } + return id_match; +} + +int getIDInScope_ByIndex(string id_name, string check_scope="") +{ + int id_index = getIDInScope_ByIndex2(id_name, check_scope); + + if(id_index < 0) + { + if(id_name.substr(id_name.length()-1,1).compare("$")==0) + id_index = getIDInScope_ByIndex2(id_name.substr(0, id_name.length()-1), check_scope); + else + id_index = getIDInScope_ByIndex2(id_name + "$", check_scope); + } + return id_index; +} + +//return the index of the id name or -1 on failure +int getIDInScope2(string id_name, string check_scope="") +{ + id_name = StringToLower(id_name); + int cs_start = 0; + int cs_length = 0; + bool match = true; + string id_scope = ""; + if(check_scope.compare("")==0) + check_scope = current_scope; + int scope_match = 0; + int tmp_match = 0; + int id_match_vecpos = -1; + for(int i = 0; i < id.size(); i++) + { + if(id_name.compare(StringToLower(id[i].name))==0 || id[i].name.compare(id_name+"$")==0) + { + //cout << endl; + //cout << "ID_NAME = " << id[i].name << endl; + //cout << "ID found in: " << id[i].scope << endl; + //cout << "Current Scope: " << check_scope << endl; + //cout << endl; + //id has to exist in or above current scope + if(check_scope.length() < id[i].scope.length()) + { + continue; + } + + //if(current_scope.find(id[i].scope)==0) + if(matchCurrentScope(id[i].scope, check_scope)) + { + //cout << "FOUND MATCH FOR [" << id[i].name << "] : " << id[i].vec_pos << " ; " << id[i].scope << endl; + return id[i].vec_pos; + } + } + } + return id_match_vecpos; +} + +int getIDInScope(string id_name, string check_scope="") +{ + if(check_scope.compare("")==0) + check_scope = current_scope; + + int id_vec = getIDInScope2(id_name, check_scope); + if(id_vec < 0) + { + if(id_name.substr(id_name.length()-1,1).compare("$")==0) + id_vec = getIDInScope2(id_name.substr(0, id_name.length()-1), check_scope); + else + id_vec = getIDInScope2(id_name + "$", check_scope); + } + return id_vec; +} + +bool isValidIDName(string name) +{ + name = StringToLower(name); + if(name.compare("")==0) + return false; + + if(name.substr(name.length()-1,1).compare("$")==0) + { + name = name.substr(0, name.length()-1); + + if(name.compare("")==0) + return false; + } + + if(!isalpha(name[0])) + return false; + + for(int i = 0; i < name.length(); i++) + { + if( (!isalnum(name[i])) && (name.substr(i,1).compare("_")!=0) ) + return false; + } + + if(isKeyWord(name)) + return false; + + return true; +} + +void set_vectorPosition(identifier &var, bool isMember = false, int utype_index = 0, int member_index = 0) +{ + if(isMember) + { + var.vec_pos = utype[utype_index].member_vec_pos[member_index]; + return; + } + + if(var.type == ID_TYPE_ARR_NUM || var.type == ID_TYPE_NUM || var.type == ID_TYPE_BYREF_NUM) + { + var.vec_pos = num_id_count; + num_id_count++; + } + else if(var.type == ID_TYPE_STR || var.type == ID_TYPE_ARR_STR || var.type == ID_TYPE_BYREF_STR) + { + var.vec_pos = str_id_count; + str_id_count++; + } + else if(var.type == ID_TYPE_USER || var.type == ID_TYPE_BYREF_USER) + { + var.vec_pos = usr_id_count; + usr_id_count++; + } +} + +int get_vectorPosition(string scope, string id_name) +{ + return -1; +} + +bool id_emit(identifier var, string dim1="_", string dim2="_", string dim3="_") +{ + //alloc_xxx ID, DIM_COUNT, DIM1_SIZE, DIM2_SIZE, DIM3_SIZE + string emit_asm = ""; + string var_id = ""; + string dim_count = ""; + string dim_size[3]; + if(var.type == ID_TYPE_ARR_NUM) + { + if(var.num_args > 0) + { + emit_asm += rc_intToString(var.num_args); + if(var.num_args == 1 && dim1.substr(0,1).compare("n")==0) + emit_asm = "dim_num1 "; + else if(var.num_args == 2 && dim1.substr(0,1).compare("n")==0 && dim2.substr(0,1).compare("n")==0) + emit_asm = "dim_num2 "; + else if(var.num_args == 3 && dim1.substr(0,1).compare("n")==0 && dim2.substr(0,1).compare("n")==0 && dim3.substr(0,1).compare("n")==0) + emit_asm = "dim_num3 "; + else + { + rc_setError("Invalid number of arguments for " + var.name); + return false; + } + } + else + { + rc_setError("Must have atleast 1 dimension in array"); + } + + + var_id = rc_intToString(getIDInScope(var.name, var.scope)); + + emit_asm += "!" + var_id + " "; + + if(var.num_args == 1) + emit_asm += dim1; + else if(var.num_args == 2) + emit_asm += dim1 + " " + dim2; + else if(var.num_args == 3) + emit_asm += dim1 + " " + dim2 + " " + dim3; + + vm_asm.push_back(emit_asm); + return true; + } + else if(var.type == ID_TYPE_ARR_STR) + { + if(var.num_args > 0) + { + emit_asm += rc_intToString(var.num_args); + if(var.num_args == 1 && dim1.substr(0,1).compare("n")==0) + emit_asm = "dim_str1 "; + else if(var.num_args == 2 && dim1.substr(0,1).compare("n")==0 && dim2.substr(0,1).compare("n")==0) + emit_asm = "dim_str2 "; + else if(var.num_args == 3 && dim1.substr(0,1).compare("n")==0 && dim2.substr(0,1).compare("n")==0 && dim3.substr(0,1).compare("n")==0) + emit_asm = "dim_str3 "; + else + { + rc_setError("Invalid number of arguments for " + var.name); + return false; + } + } + else + { + rc_setError("Must have atleast 1 dimension in array"); + } + + + var_id = rc_intToString(getIDInScope(var.name, var.scope)); + + emit_asm += "!" + var_id + " "; + + if(var.num_args == 1) + emit_asm += dim1; + else if(var.num_args == 2) + emit_asm += dim1 + " " + dim2; + else if(var.num_args == 3) + emit_asm += dim1 + " " + dim2 + " " + dim3; + + vm_asm.push_back(emit_asm); + return true; + } + else if(var.type == ID_TYPE_USER) + { + emit_asm = "dim_type "; + + if(var.num_args > 0) + { + emit_asm += rc_intToString(var.num_args); + if(var.num_args == 1 && dim1.substr(0,1).compare("n")==0) + emit_asm = "dim_type1 "; + else if(var.num_args == 2 && dim1.substr(0,1).compare("n")==0 && dim2.substr(0,1).compare("n")==0) + emit_asm = "dim_type2 "; + else if(var.num_args == 3 && dim1.substr(0,1).compare("n")==0 && dim2.substr(0,1).compare("n")==0 && dim3.substr(0,1).compare("n")==0) + emit_asm = "dim_type3 "; + else + { + rc_setError("Invalid number of arguments for " + var.name); + return false; + } + } + + var_id = rc_intToString(getIDInScope(var.name, var.scope)); + + emit_asm += "!" + var_id + " !" + rc_intToString(var.type_index) + " "; + + if(var.num_args == 1) + emit_asm += dim1; + else if(var.num_args == 2) + emit_asm += dim1 + " " + dim2; + else if(var.num_args == 3) + emit_asm += dim1 + " " + dim2 + " " + dim3; + + + vm_asm.push_back(emit_asm); + return true; + } + else + { + //rc_setError("Could not identify type"); + //return false; + } + + return true; +} + +bool create_type_members(int id_index, int type_index) +{ + //cout << "start type_member" << endl; + //cout << "id_index = " << id_index << endl; + //cout << "utype_index = " << id[id_index].type_index << endl; + //cout << "num_members = " << utype[0].num_members << endl; + identifier var; + int utype_index = id[id_index].type_index; + int member_index = 0; + user_array_dim d; + if( (id_index < 0 || id_index >= id.size()) || (utype_index < 0 || utype_index >= utype.size()) ) + return true; + for(int i = 0; i < utype[utype_index].num_members; i++) + { + member_index = id.size(); + var.name = StringToLower(utype[utype_index].member_name[i]); + var.type = utype[utype_index].member_type[i]; + var.type_index = utype[utype_index].member_utype_index[i]; + var.isChild = true; + var.parent_index = id_index; + set_vectorPosition(var, true, utype_index, i); + //cout << "vec -> " << var.vec_pos << endl; + var.scope = StringToLower(id[id_index].scope + "." + id[id_index].name); + var.num_args = utype[utype_index].member_dim_count[i]; + var.dim_size[0] = utype[utype_index].member_dim[i].dim_size[0]; + var.dim_size[1] = utype[utype_index].member_dim[i].dim_size[1]; + var.dim_size[2] = utype[utype_index].member_dim[i].dim_size[2]; + //cout << "member = " << var.name << " : " << var.vec_pos << endl; + //cout << "member_type = " << var.type << endl; + //cout << "member_type_index = " << var.type_index << endl; + + id.push_back(var); + //id_emit(var); + if(var.type = ID_TYPE_USER) + { + if(!create_type_members(member_index, var.type_index)) + { + rc_setError("Could not create member " + var.name + " inside " + var.scope); + return false; + } + } + } + //cout << "end type_member" << endl; + return true; +} + +bool create_variable(string name, int type, string utype_name="", int vec = -1) +{ + identifier var; + var.name = name; + var.type = type; + var.isArrayArg = false; + if(name.substr(0,1).compare("#")==0) + var.scope = "main"; + else + var.scope = current_scope; + if(var.type == ID_TYPE_USER || var.type == ID_TYPE_BYREF_USER) + { + var.type_index = getUType(utype_name); + if(var.type_index < 0) + { + rc_setError("Type \"" + utype_name +"\" does not exists"); + return false; + } + int var_index = id.size(); + var.num_args = 0; + var.parent_index = -1; + set_vectorPosition(var); + id.push_back(var); + + if(isInFunctionScope && !isFunctionArg_flag) + { + vm_asm.push_back("preset_t !" + rc_intToString(var.vec_pos) + " !" + rc_intToString(var.type_index)); + } + else if(!isFunctionArg_flag) + id_emit(var); + //create all sub variables here + create_type_members(var_index, var.type_index); + } + else + { + var.num_args = 0; + if(vec == -1) + { + set_vectorPosition(var); + //cout << var.name << " <==> " << var.vec_pos << endl; + } + else + { + //cout << "set " << name << " to " << vec << endl; + var.vec_pos = vec; + } + + + id.push_back(var); + id_emit(var); + } + + if(isInFunctionScope && !isFunctionArg_flag) + { + if(var.type == ID_TYPE_NUM || var.type == ID_TYPE_ARR_NUM) + vm_asm.push_back("preset !" + rc_intToString(var.vec_pos) ); + else if(var.type == ID_TYPE_STR || var.type == ID_TYPE_ARR_STR) + vm_asm.push_back("preset$ !" + rc_intToString(var.vec_pos)); + } + isFunctionArg_flag = false; + + return true; +} + +bool create_array(string name, int type, string utype_name, int dim_count, string dim1="", string dim2="", string dim3="", int vec = -1) +{ + identifier var; + var.name = name; + var.type = type; + var.scope = current_scope; + var.isArrayArg = false; + if(var.type == ID_TYPE_USER) + { + var.type_index = getUType(utype_name); + if(var.type_index < 0) + { + rc_setError(utype_name + " does not name a type"); + return false; + } + var.num_args = dim_count; + if(dim_count < 1 || dim_count > 3) + { + rc_setError("Array must be in the range of 1 to 3 dimensions"); + return false; + } + int var_index = id.size(); + set_vectorPosition(var); + id.push_back(var); + + if(isInFunctionScope) + { + switch(var.num_args) + { + case 0: + vm_asm.push_back("preset_t !" + rc_intToString(var.vec_pos) + " !" + rc_intToString(var.type_index)); + break; + case 1: + vm_asm.push_back("preset_t1 !" + rc_intToString(var.vec_pos) + " !" + rc_intToString(var.type_index) + " " + dim1); + break; + case 2: + vm_asm.push_back("preset_t2 !" + rc_intToString(var.vec_pos) + " !" + rc_intToString(var.type_index) + " " + dim1 + " " + dim2); + break; + case 3: + vm_asm.push_back("preset_t3 !" + rc_intToString(var.vec_pos) + " !" + rc_intToString(var.type_index) + " " + dim1 + " " + dim2 + " " + dim3); + break; + } + } + else + id_emit(var, dim1, dim2, dim3); + + //create all sub variables here + create_type_members(var_index, var.type_index); + } + else + { + var.num_args = dim_count; + if(dim_count < 1 || dim_count > 3) + { + rc_setError("Array must be in the range of 1 to 3 dimensions"); + return false; + } + if(vec == -1) + { + set_vectorPosition(var); + id.push_back(var); + id_emit(var, dim1, dim2, dim3); + } + else + { + var.vec_pos = vec; + id.push_back(var); + } + } + + if((isInFunctionScope && !isFunctionArg_flag) && enable_presets) + { + if(var.type == ID_TYPE_NUM || var.type == ID_TYPE_ARR_NUM) + vm_asm.push_back("preset !" + rc_intToString(var.vec_pos) ); + else if(var.type == ID_TYPE_STR || var.type == ID_TYPE_ARR_STR) + vm_asm.push_back("preset$ !" + rc_intToString(var.vec_pos)); + } + isFunctionArg_flag = false; + + return true; +} + +bool embed_function(string name, int type) +{ + if(getIDInScope(name) >= 0) + { + rc_setError("Identifier [" + name + "] already exists in this scope"); + return false; + } + + current_scope = "main." + name; + isInFunctionScope = true; + + switch(type) + { + case ID_TYPE_SUB: + current_block_state = BLOCK_STATE_SUB; + break; + case ID_TYPE_FN_NUM: + case ID_TYPE_FN_STR: + current_block_state = BLOCK_STATE_FUNCTION; + break; + default: + rc_setError("Invalid type for function definition"); + return false; + } + + fn_numCount = 0; + fn_strCount = 0; + fn_usrCount = 0; + fn_byref_numCount = 0; + fn_byref_strCount = 0; + fn_byref_usrCount = 0; + + identifier fn; + fn.name = name; + fn.scope = "main"; + fn.type = type; + fn.isBuiltin = true; + fn.vmFunctionIndex = current_vmFunction_index; + current_vmFunction_index++; + + fn.num_args = 0; //function args default to 0; args are added with add_function_args + current_fn_index = id.size(); + id.push_back(fn); + return true; +} + +bool add_embedded_arg(string arg_name, int arg_type) +{ + //fn_arg + //fn_arg_type + //fn_arg_utype + int fn_index = current_fn_index; + id[fn_index].fn_arg.push_back(arg_name); + id[fn_index].fn_arg_type.push_back(arg_type); + + string fn_id = ""; + int fn_id_index = -1; + + if(arg_type == ID_TYPE_NUM) + { + fn_id = "#fn" + rc_intToString(fn_numCount); + if(getIDInScope(fn_id) < 0) + create_variable(fn_id, ID_TYPE_NUM, ""); + fn_numCount++; + } + else if(arg_type == ID_TYPE_STR) + { + fn_id = "#fs" + rc_intToString(fn_strCount); + if(getIDInScope(fn_id) < 0) + create_variable(fn_id, ID_TYPE_STR); + fn_strCount++; + } + else if(arg_type == ID_TYPE_BYREF_NUM) + { + fn_id = "#fn" + rc_intToString(fn_numCount); + if(getIDInScope(fn_id) < 0) + create_variable(fn_id, ID_TYPE_BYREF_NUM); + fn_numCount++; + } + else if(arg_type == ID_TYPE_BYREF_STR) + { + fn_id = "#fs" + rc_intToString(fn_strCount); + if(getIDInScope(fn_id) < 0) + create_variable(fn_id, ID_TYPE_BYREF_STR); + fn_strCount++; + } + else + { + rc_setError("Invalid type in function definition"); + return false; + } + + int fn_arg_vec = getIDInScope(fn_id); + //cout << fn_id << " ====> " << fn_arg_vec << endl; + + isFunctionArg_flag = true; + + create_variable(arg_name, arg_type, "", fn_arg_vec); + + id[fn_index].fn_reg.push_back( fn_id ); + id[fn_index].fn_arg_vec.push_back(fn_arg_vec); + id[fn_index].num_args++; + + fid_vector_entry f_entry; + f_entry.type = arg_type; + f_entry.vec_str = "!" + rc_intToString(fn_arg_vec); + + id[fn_index].fn_var.push_back( f_entry ); + + return true; +} + +bool create_function(string name, int type, string utype_name) +{ + if(getIDInScope(name) >= 0) + { + rc_setError("Identifier [" + name + "] already exists in this scope"); + return false; + } + + current_scope += "." + name; + isInFunctionScope = true; + current_fn_id_count = 0; + + switch(type) + { + case ID_TYPE_SUB: + current_block_state = BLOCK_STATE_SUB; + break; + case ID_TYPE_FN_NUM: + case ID_TYPE_FN_STR: + current_block_state = BLOCK_STATE_FUNCTION; + break; + case ID_TYPE_FN_USER: + current_block_state = BLOCK_STATE_FUNCTION; + break; + default: + rc_setError("Invalid type for function definition"); + return false; + } + + fn_numCount = 0; + fn_strCount = 0; + fn_usrCount = 0; + fn_byref_numCount = 0; + fn_byref_strCount = 0; + fn_byref_usrCount = 0; + + vm_asm.push_back(".data"); + vm_asm.push_back("label " + name); + + identifier fn; + fn.name = name; + fn.scope = "main"; + fn.type = type; + fn.type_index = getUType(utype_name); + + if(type == ID_TYPE_FN_USER && fn.type_index < 0) + { + rc_setError("Type \"" + utype_name + "\" does not exists"); + return false; + } + + fn.isBuiltin = false; + fn.isArrayArg = false; + fn.fn_var.clear(); + + int id_index = id.size(); + + fn.num_args = 0; //function args default to 0; args are added with add_function_args + current_fn_index = id.size(); + id.push_back(fn); + + if(fn.type == ID_TYPE_FN_USER) + create_type_members(id_index, fn.type_index); + + return true; +} + +bool add_function_arg(string arg_name, int arg_type, string utype_name) +{ + //fn_arg + //fn_arg_type + //fn_arg_utype + int fn_index = current_fn_index; + id[fn_index].fn_arg.push_back(arg_name); + id[fn_index].fn_arg_type.push_back(arg_type); + + isFunctionArg_flag = true; + + //cout << "ARG = " << arg_name << " type = " << arg_type << endl; + + if(!create_variable(arg_name, arg_type, utype_name)) + { + rc_setError("Invalid argument in Function definition"); + return false; + } + + //id[fn_index].fn_reg.push_back( fn_id ); + int arg_id_vec = getIDInScope(arg_name); + int arg_id_index = getIDInScope_ByIndex(arg_name); + + if(arg_id_index < 0) + { + rc_setError("Could not create argument of type \"" + utype_name + "\""); + return false; + } + + id[fn_index].fn_arg_vec.push_back( arg_id_vec ); + id[fn_index].fn_arg_utype.push_back( id[arg_id_index].type_index ); + id[fn_index].num_args++; + + return true; +} + +bool create_function_variable(string arg_name, int arg_type, string utype_name="") +{ + //fn_arg + //fn_arg_type + //fn_arg_utype + int fn_index = current_fn_index; + + create_variable(arg_name, arg_type, utype_name); + + return true; +} + +bool create_function_array(string arg_name, int arg_type, int dim_count, string dim1, string dim2, string dim3) +{ + //fn_arg + //fn_arg_type + //fn_arg_utype + int fn_index = current_fn_index; + + create_array(arg_name, arg_type, "", dim_count, dim1, dim2, dim3); + + return true; +} + +bool set_scope(string scope) +{ + current_scope = scope; + return false; +} + +bool exit_scope(int num_levels) +{ + if(num_levels <= 0) + return false; + int lv = 0; + string scope = current_scope; + for(int i = scope.length()-1; i > 0; i--) + { + if(scope.substr(i,1).compare(".")==0) + { + lv++; + scope = scope.substr(0,i); + if(lv==num_levels) + { + current_scope = scope; + return true; + } + } + } + current_scope = scope; + return false; +} + +bool enter_scope(string sub_scope) +{ + return false; +} + +int getIDIndex(string id_name) +{ + id_name = StringToLower(id_name); + + for(int i = 0; i < id.size(); i++) + { + if(id[i].name.compare(id_name)==0) + return i; + } + return -1; +} + + +/*type definitions header +------------------------------- +num types + +type #1 num fields + field #1 type (0 - num, 1 - str, 3 - udt) + field #1 num dimensions + ... + field # type (0 - num, 1 - str, 3 - udt) + field # num dimensions + +type # num fields + field #1 type (0 - num, 1 - str, 3 - udt) + field #1 num dimensions + ... + field # type (0 - num, 1 - str, 3 - udt) + field # num dimensions +*/ + +#endif // IDENTIFIER_H_INCLUDED diff --git a/rcbasic_build/keywords.h b/rcbasic_build/keywords.h new file mode 100644 index 0000000..73e7cbd --- /dev/null +++ b/rcbasic_build/keywords.h @@ -0,0 +1,48 @@ +#ifndef KEYWORDS_H_INCLUDED +#define KEYWORDS_H_INCLUDED + +using namespace std; + +string keyWords[] = { + "AND", //1 + "OR", //2 + "XOR", //3 + "EXIT", //4 + "MOD", //5 + "SHL", //6 + "SHR", //7 + "FUNCTION", //8 + "RETURN", //9 + "DIM", //10 + "END", //11 + "FOR", //12 + "TO", //13 + "STEP", //14 + "NEXT", //15 + "WHILE", //16 + "WEND", //17 + "DO", //18 + "LOOP", //19 + "UNTIL", //20 + "SELECT", //21 + "CASE", //22 + "DEFAULT", //23 + "IF", //24 + "ELSE", //25 + "THEN", //26 + "DELETE", //27 + "INCLUDE", //30 + "BYREF", //31 + "PRINT", //32 + "SUB", //33 + "NOT", //34 + "ELSEIF", //35 + "REDIM", //, //36 + "CONST", //37 + "ONCE", //38 + "CONTINUE", //39 + "AS", //40 + "TYPE" //41 +}; + +#endif // KEYWORDS_H_INCLUDED diff --git a/rcbasic_build/main.cpp b/rcbasic_build/main.cpp new file mode 100644 index 0000000..0a04fe7 --- /dev/null +++ b/rcbasic_build/main.cpp @@ -0,0 +1,1173 @@ +#include +#include +#include +#include +#include +#include +#include "tokenizer.h" +#include "parser.h" +#include "rc_builtin.h" +#include "rc_vm_asm.h" +#include "file_directory.h" +#include "env_resolve.h" +#include "identifier.h" + +using namespace std; + + +struct rc_src +{ + string filename = ""; + uint64_t line_number = 1; + uint64_t line_position = 0; + bool eof_reached = false; + uint64_t dbg_inc_index = 0; +}; + +stack rcbasic_program; +fstream rcbasic_file; + +vector inc_once; + +bool rcbasic_build_debug = false; +uint64_t rcbasic_user_var_start = 0; + +vector inc_files; + +void rcbasic_init() +{ + create_type("null"); + + //init built-in functions here + + block_state.push(BLOCK_STATE_MAIN); + current_block_state = BLOCK_STATE_MAIN; + + current_scope = "main"; + vm_asm.push_back(".code"); + + init_embedded(); + + //cout << "numid_count = " << num_id_count << endl; + //cout << "strid_count = " << str_id_count << endl << endl; + + block_state.push(BLOCK_STATE_MAIN); + current_block_state = BLOCK_STATE_MAIN; + isInFunctionScope = false; + + current_scope = "main"; + vm_asm.push_back(".code"); +} + +void rcbasic_dev_init() +{ + create_type("null"); + + //init built-in functions here + + block_state.push(BLOCK_STATE_MAIN); + current_block_state = BLOCK_STATE_MAIN; + + current_scope = "main"; + vm_asm.push_back(".code"); + + cout << "numid_count = " << num_id_count << endl; + cout << "strid_count = " << str_id_count << endl << endl; + + block_state.push(BLOCK_STATE_MAIN); + current_block_state = BLOCK_STATE_MAIN; + isInFunctionScope = false; + + current_scope = "main"; + vm_asm.push_back(".code"); +} + +bool rcbasic_loadProgram(string src_file) +{ + rc_src rc_program; + rc_program.filename = src_file; + rc_program.line_number = 1; + rc_program.line_position; + rc_program.dbg_inc_index = inc_files.size(); + rcbasic_file.open(src_file.c_str(), fstream::in); + if(rcbasic_file.is_open()) + { + rcbasic_program.push(rc_program); + inc_files.push_back(src_file); + return true; + } + return false; +} + +bool rc_preprocessor() +{ + rc_src inc_file; + if(tmp_token.size()>0) + { + if(tmp_token[0].compare("")==0) + { + if(tmp_token.size() != 2) + { + rc_setError("Expected string literal or flag in INCLUDE"); + return false; + } + + //cout << "tmp_token[1] == " << tmp_token[1] << endl; + + if(tmp_token[1].compare("")==0) + { + tmp_token.clear(); + inc_once.push_back(rcbasic_program.top().filename); + return true; + } + + if(tmp_token[1].substr(0,8).compare("")!=0) + { + rc_setError("Expected include file as string constant"); + return false; + } + + tmp_token[1] = resolveEnvironmentVariables(tmp_token[1]); + + inc_file.filename = tmp_token[1].substr(8); + inc_file.filename = rc_absFilePath(inc_file.filename); + + for(int i = 0; i < inc_once.size(); i++) + { + if(inc_once[i].compare(inc_file.filename)==0) + { + tmp_token.clear(); + //cout << "DEBUG INC_ONCE: " << inc_file.filename << " can only be included once" << endl; + return true; + } + } + + //cout << "\nDEBUG INCLUDE ABS_PATH:" << inc_file.filename << endl << endl; + inc_file.line_number = 0; + inc_file.line_position = 0; + inc_file.dbg_inc_index = inc_files.size(); + rcbasic_file.close(); + rcbasic_file.open(inc_file.filename.c_str(), fstream::in); + if(!rcbasic_file.is_open()) + { + rc_setError("Could not open " + inc_file.filename); + return false; + } + + //increase current file line number before pushing next file on stack + rcbasic_program.top().line_number++; + + rcbasic_program.push(inc_file); + inc_files.push_back(inc_file.filename); + tmp_token.clear(); + return true; + } + } + return true; +} + +bool Array_Macros(int tmp_start_token) +{ + //returning true is just saying there were no syntax errors found + if(tmp_token[tmp_start_token].length() < 5) + return true; + if(StringToLower(tmp_token[tmp_start_token].substr(4)).compare("arraydim")!=0 && StringToLower(tmp_token[tmp_start_token].substr(4)).compare("arraysize")!=0 && + StringToLower(tmp_token[tmp_start_token].substr(4)).compare("arraycopy")!=0 && StringToLower(tmp_token[tmp_start_token].substr(4)).compare("arrayfill")!=0) + return true; + + int64_t arr_id = 0; + vector tmp_macro_token; + vector tmp_current_token; + //int ArrayDim_id = getIDInScope_ByIndex("ArrayDim"); + for(int i = tmp_start_token; i < tmp_token.size(); i++) + { + if(tmp_token[i].substr(0,4).compare("")==0) + { + if(StringToLower(tmp_token[i].substr(4)).compare("arraydim")==0) + { + if(tmp_token[i+1].compare("")!=0) + { + rc_setError("Invalid use of ArrayDim"); + return false; + } + if(tmp_token[i+2].substr(0,4).compare("")==0) + { + arr_id = getIDInScope_ByIndex(tmp_token[i+2].substr(4)); + if(arr_id < 0) + { + rc_setError("Identifier must be declared before call to ArrayDim"); + return false; + } + + id[arr_id].isArrayArg = true; + + } + else + { + rc_setError("Expected Identifier in ArrayDim"); + return false; + } + + int end_token = i+2; + int expr_scope = 1; + for(end_token; end_token < tmp_token.size(); end_token++) + { + if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope++; + else if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope--; + + if(expr_scope==0 && tmp_token[end_token].compare("")==0) + break; + } + + tmp_macro_token.clear(); + for(int n = i; n <= end_token; n++) + tmp_macro_token.push_back(tmp_token[n]); + + //cout << "<---- DEBUG ---->" << i << endl; + //for(int n = 0; n < token.size(); n++) + // cout <<"token[" << n << "] = " << token[n] << endl; + + tmp_current_token.clear(); + for(int n = 0; n < token.size(); n++) + tmp_current_token.push_back(token[n]); + + token.clear(); + for(int n = 0; n < tmp_macro_token.size(); n++) + token.push_back(tmp_macro_token[n]); + + //for(int n = 0; n < token.size(); n++) + // cout <<"new token[" << n << "] = " << token[n] << endl; + + + if(!eval_expression()) + { + rc_setError("Could not evaluate ArrayDim"); + return false; + } + + for(int n = i; n <= end_token; n++) + tmp_token[n] = token[n-i]; + + token.clear(); + for(int n = 0; n < tmp_current_token.size(); n++) + token.push_back(tmp_current_token[n]); + + //for(int n = 0; n < token.size(); n++) + // cout <<"final token[" << n << "] = " << token[n] << endl; + return true; + + } + else if(StringToLower(tmp_token[i].substr(4)).compare("arraysize")==0) + { + if(tmp_token[i+1].compare("")!=0) + { + rc_setError("Invalid use of ArraySize"); + return false; + } + if(tmp_token[i+2].substr(0,4).compare("")==0) + { + arr_id = getIDInScope_ByIndex(tmp_token[i+2].substr(4)); + if(arr_id < 0) + { + rc_setError("Identifier must be declared before call to ArraySize"); + return false; + } + + id[arr_id].isArrayArg = true; + + } + else + { + rc_setError("Expected Identifier in ArraySize"); + return false; + } + + int end_token = i+2; + int expr_scope = 1; + for(end_token; end_token < tmp_token.size(); end_token++) + { + if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope++; + else if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope--; + + if(expr_scope==0 && tmp_token[end_token].compare("")==0) + break; + } + + tmp_macro_token.clear(); + for(int n = i; n <= end_token; n++) + tmp_macro_token.push_back(tmp_token[n]); + + + tmp_current_token.clear(); + for(int n = 0; n < token.size(); n++) + tmp_current_token.push_back(token[n]); + + token.clear(); + for(int n = 0; n < tmp_macro_token.size(); n++) + token.push_back(tmp_macro_token[n]); + + if(!eval_expression(0, token.size()-1, true))//i, end_token)) + { + rc_setError("Could not evaluate ArraySize expression"); + //for(int n = 0; n < token.size(); n++) + // cout << "token["<< n << "] = " << token[n] << endl; + return false; + } + + for(int n = i; n <= end_token; n++) + tmp_token[n] = token[n-i]; + + token.clear(); + for(int n = 0; n < tmp_current_token.size(); n++) + token.push_back(tmp_current_token[n]); + + return true; + } + else if(StringToLower(tmp_token[i].substr(4)).compare("arraycopy")==0) + { + if(tmp_token.size() < 5) + { + rc_setError("Ivalid use of ArrayCopy"); + return false; + } + + if(tmp_token[i+1].compare("")!=0) + { + rc_setError("Invalid use of ArrayCopy"); + return false; + } + + if(tmp_token[i+2].substr(0,4).compare("")==0) + { + arr_id = getIDInScope_ByIndex(tmp_token[i+2].substr(4)); + if(arr_id < 0) + { + rc_setError("Identifier must be declared before call to ArrayCopy"); + return false; + } + + id[arr_id].isArrayArg = true; + + } + else + { + rc_setError("Expected Identifier in ArrayCopy"); + return false; + } + + if(!tmp_token[i+3].substr(0,7).compare("")==0) + { + rc_setError("Expected comma in ArrayCopy"); + return false; + } + + if(tmp_token[i+4].substr(0,4).compare("")==0) + { + arr_id = getIDInScope_ByIndex(tmp_token[i+4].substr(4)); + if(arr_id < 0) + { + rc_setError("Identifier must be declared before call to ArrayCopy"); + return false; + } + + id[arr_id].isArrayArg = true; + + } + else + { + rc_setError("Expected Identifier in ArrayCopy"); + return false; + } + + int end_token = i+4; + int expr_scope = 1; + for(end_token; end_token < tmp_token.size(); end_token++) + { + if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope++; + else if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope--; + + if(expr_scope==0 && tmp_token[end_token].compare("")==0) + break; + } + + tmp_macro_token.clear(); + for(int n = i; n <= end_token; n++) + tmp_macro_token.push_back(tmp_token[n]); + + //cout << "<---- DEBUG ---->" << i << endl; + //for(int n = 0; n < token.size(); n++) + // cout <<"token[" << n << "] = " << token[n] << endl; + + tmp_current_token.clear(); + for(int n = 0; n < token.size(); n++) + tmp_current_token.push_back(token[n]); + + token.clear(); + for(int n = 0; n < tmp_macro_token.size(); n++) + token.push_back(tmp_macro_token[n]); + + //for(int n = 0; n < token.size(); n++) + // cout <<"new token[" << n << "] = " << token[n] << endl; + + + if(!eval_expression()) + { + rc_setError("Could not evaluate ArrayCopy"); + return false; + } + + for(int n = i; n <= end_token; n++) + tmp_token[n] = token[n-i]; + + token.clear(); + for(int n = 0; n < tmp_current_token.size(); n++) + token.push_back(tmp_current_token[n]); + + //for(int n = 0; n < token.size(); n++) + // cout <<"final token[" << n << "] = " << token[n] << endl; + return true; + + } + else if(StringToLower(tmp_token[i].substr(4)).compare("arrayfill")==0) + { + if(tmp_token[i+1].compare("")!=0) + { + rc_setError("Invalid use of ArrayFill"); + return false; + } + if(tmp_token[i+2].substr(0,4).compare("")==0) + { + arr_id = getIDInScope_ByIndex(tmp_token[i+2].substr(4)); + if(arr_id < 0) + { + rc_setError("Identifier must be declared before call to ArrayFill"); + return false; + } + + id[arr_id].isArrayArg = true; + + } + else + { + rc_setError("Expected Identifier in ArrayFill"); + return false; + } + + int end_token = i+2; + int expr_scope = 1; + for(end_token; end_token < tmp_token.size(); end_token++) + { + if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope++; + else if(tmp_token[end_token].compare("")==0 || tmp_token[end_token].compare("")==0) + expr_scope--; + + if(expr_scope==0 && tmp_token[end_token].compare("")==0) + break; + } + + tmp_macro_token.clear(); + for(int n = i; n <= end_token; n++) + tmp_macro_token.push_back(tmp_token[n]); + + //cout << "<---- DEBUG ---->" << i << endl; + //for(int n = 0; n < token.size(); n++) + // cout <<"token[" << n << "] = " << token[n] << endl; + + tmp_current_token.clear(); + for(int n = 0; n < token.size(); n++) + tmp_current_token.push_back(token[n]); + + token.clear(); + for(int n = 0; n < tmp_macro_token.size(); n++) + token.push_back(tmp_macro_token[n]); + + //for(int n = 0; n < token.size(); n++) + // cout <<"new token[" << n << "] = " << token[n] << endl; + + + if(!eval_expression()) + { + rc_setError("Could not evaluate ArrayFill"); + return false; + } + + for(int n = i; n <= end_token; n++) + tmp_token[n] = token[n-i]; + + token.clear(); + for(int n = 0; n < tmp_current_token.size(); n++) + token.push_back(tmp_current_token[n]); + + //for(int n = 0; n < token.size(); n++) + // cout <<"final token[" << n << "] = " << token[n] << endl; + return true; + + } + } + } + return false; +} + +bool rc_eval(string line) +{ + //adding an extra character to line to avoid a memory leak + line += " "; + + + ERROR_MSG = ""; + clearRegs(); + clearTokens(); + if(line.compare("#var")==0) + { + output_vars(); + return true; + } + + //cout << "get tokens" << endl; + if(!tokens(line)) + { + //cout << "Error1: " << rc_getError() << endl; + return false; + } + + //current_Debug + //cout << "-------BEFORE PP START TOKENS--------" << endl; + //output_tokens(); + + //cout << "get preprocessor" << endl; + if(!rc_preprocessor()) + { + return false; + } + + //cout << "-------AFTER PP START TOKENS--------" << endl; + //output_tokens(); cout << endl; + + //cout << "check rule" << endl; + //cout << "token: " << token[0] << endl; + + int i = 0; + + int dim_scope = 0; + bool is_dim_expr = false; + string dim_token = ""; + + for(i = 0; i < tmp_token.size(); i++) + { + if(tmp_token[i].compare("")==0 || tmp_token[i].compare("")==0) + { + dim_token = tmp_token[i]; + dim_scope = 0; + is_dim_expr = true; + continue; + } + + if(tmp_token[i].compare("")==0 || tmp_token[i].compare("")==0) + dim_scope++; + + if(tmp_token[i].compare("")==0 || tmp_token[i].compare("")==0) + dim_scope--; + + if(is_dim_expr==true && dim_scope==0 && tmp_token[i].compare("")==0) + { + tmp_token[i] = "<:>"; + tmp_token.insert(tmp_token.begin()+ (i+1), dim_token); + } + + if(tmp_token[i].compare("<:>")==0) + is_dim_expr = false; + } + + i = 0; + + while( i < tmp_token.size()) + { + token.clear(); + + for(; i < tmp_token.size(); i++) + { + //cout << "start tmp_token loop :: "; + //cout << "i = " << i << " tmp_token_size = " << tmp_token.size() << endl; + if(tmp_token[i].compare("<:>")==0) + break; + else if(!Array_Macros(i)) + { + //cout << "ERROR:" << rc_getError() << endl; + return false; + } + //cout << "### tmp_token[" << i << "] = "; + //cout << tmp_token[i] << endl; + token.push_back(tmp_token[i]); + } + i++; + + //cout << "start rule" << endl; + + if(!check_rule()) + { + //cout << "ERROR:" << rc_getError() << endl; + return false; + } + } + + return true; + + //if(!eval_expression()) + // cout << "Error2: " << rc_getError() << endl; + //cout << endl << endl << "----TOKENS-----" << endl; + //output_tokens(); + + //cout << endl << "VM CODE" << endl << endl; + //debug_output_VMASM(); + + //cout << "F_Error: " << rc_getError() << endl; +} + +bool rc_eval_embedded(string line) +{ + //adding an extra character to line to avoid a memory leak + line += " "; + + + ERROR_MSG = ""; + clearRegs(); + clearTokens(); + if(line.compare("#var")==0) + { + output_vars(); + } + + if(!tokens(line)) + { + cout << "Error1: " << rc_getError() << endl; + return false; + } + + if(tmp_token.size()==0) + return true; + //cout << "-------START TOKENS--------" << endl; + //output_tokens(); + + token.clear(); + for(int i = 0; i < tmp_token.size(); i++) + token.push_back(tmp_token[i]); + + if(!check_rule_embedded()) + { + cout << "---ERROR:" << rc_getError() << endl; + output_tokens(); + cout << endl; + return false; + } + + return true; + + //if(!eval_expression()) + // cout << "Error2: " << rc_getError() << endl; + //cout << endl << endl << "----TOKENS-----" << endl; + //output_tokens(); + + //cout << endl << "VM CODE" << endl << endl; + //debug_output_VMASM(); + + //cout << "F_Error: " << rc_getError() << endl; +} + +rc_src rc_last_line; + +bool rc_getline(string &line) +{ + line = ""; + + getline(rcbasic_file, line); + + if(!rcbasic_file.eof()) + { + return true; + } + else if(!rcbasic_program.top().eof_reached) + { + //cout << "setting negative line in " << rcbasic_program.top().filename << " at line " << rcbasic_program.top().line_number << endl; + rcbasic_program.top().eof_reached = true; // end of file + return true; + } + else + { + rcbasic_file.close(); + + while(rcbasic_program.size()>0) + { + //cout << "debug STACK: " << rcbasic_program.top().filename << " -- " << rcbasic_program.top().line_number << ":" << rcbasic_program.top().line_position << endl; + if(rcbasic_program.top().eof_reached) + { + //cout << "popping " << rcbasic_program.top().filename << endl; + rcbasic_program.pop(); + //cout << "new size = " << rcbasic_program.size() << endl; + } + else + { + //cout << "reopening " << rcbasic_program.top().filename << " at line " << rcbasic_program.top().line_number << ":" << rcbasic_program.top().line_position << endl; + rcbasic_file.open(rcbasic_program.top().filename.c_str(), fstream::in); + if(!rcbasic_file.is_open()) + { + cout << "Could not open " << rcbasic_program.top().filename << endl; + return false; + } + rcbasic_file.seekg(rcbasic_program.top().line_position); + getline(rcbasic_file, line); + return true; + } + } + return false; + } +} + +bool rcbasic_compile() +{ + int current_file = 0; + string line = ""; + fstream f; + + string rc_asm_file = "main.rc_asm"; + string rc_str_data = "main_str_data.sdata"; + + if(is_file_exist(rc_asm_file.c_str())) + { + if(remove(rc_asm_file.c_str())!=0) + { + cout << "Could not clear asm file" << endl; + return false; + } + } + + if(is_file_exist(rc_str_data.c_str())) + { + if(remove(rc_str_data.c_str())!=0) + { + cout << "Could not clear sdata file" << endl; + return false; + } + } + + while( rc_getline(line) ) + { + if(rcbasic_build_debug) + { + vm_asm.push_back("dbg uint=0 uint=" + rc_uint64ToString(rcbasic_program.top().dbg_inc_index) + " uint=" + rc_uint64ToString(rcbasic_program.top().line_number)); + } + cout << "line " << rcbasic_program.top().line_number << ": " << rcbasic_file.tellg() << " -> " << line << endl; + if(!rcbasic_program.top().eof_reached) + rcbasic_program.top().line_position = rcbasic_file.tellg(); + //vm_asm.push_back("mov n0 " + rc_intToString(rcbasic_program.top().line_number)); + //vm_asm.push_back("print n0"); + if(!rc_eval(line)) + { + cout << "Error on Line " << rcbasic_program.top().line_number << " in " << rcbasic_program.top().filename << ": " << rc_getError() << endl; + //output_tokens(); + cout << endl; + return false; + } + rcbasic_program.top().line_number++; +// if(rcbasic_program.top().line_number % 500 == 0) +// { +// f.open(rc_asm_file.c_str(), fstream::app); +// for(int i = 0; i < vm_asm.vm_code.size(); i++) +// f << vm_asm.vm_code[i] << endl; +// f.close(); +// vm_asm.clear(); +// +// f.open(rc_str_data.c_str(), fstream::app | fstream::binary); +// for(int i = 0; i < data_segment.size(); i++) +// f.put(data_segment[i]); +// f.close(); +// data_segment.clear(); +// } + } + + if(rcbasic_build_debug) + { + vm_asm.push_back("dbg uint=0 uint=0 uint=0"); //I just need to call this at the end so it will output the last line messages + } + vm_asm.push_back("end"); + + f.open(rc_asm_file.c_str(), fstream::app); + for(int i = 0; i < vm_asm.vm_code.size(); i++) + f << vm_asm.vm_code[i] << endl; + f.close(); + vm_asm.clear(); + + f.open(rc_str_data.c_str(), fstream::app | fstream::binary); + for(int i = 0; i < data_segment.size(); i++) + f.put(data_segment[i]); + f.close(); + data_segment.clear(); + + return true; + + //f.open("tst_var_output.txt", fstream::out | fstream::trunc); + + //for(int i = 0; i < id.size(); i++) + // f << id[i].name << " -> " << id[i].vec_pos << endl; + //f.close(); + + //cout << endl << "VM Code" << endl << "---------------------" << endl; + //debug_output_VMASM(); +} + +void rcbasic_export_dev() +{ + string fn_line = ""; + fstream f("rcbasic_dev.txt", fstream::out | fstream::trunc); + fstream f2("rcbasic_dev2.txt", fstream::out | fstream::trunc); + fstream f3("rcbasic_dev3.txt", fstream::out | fstream::trunc); + + if(!f.is_open()) + return; + string output_line = ""; + for(int i = 0; i < id.size(); i++) + { + fn_line = "#define FN_" + id[i].name + " " + rc_intToString(id[i].vmFunctionIndex); + + output_line = "embed_function(\"" + id[i].name +"\", "; + switch(id[i].type) + { + case ID_TYPE_FN_NUM: + output_line += "ID_TYPE_FN_NUM);"; + f2 << fn_line << endl; + f3 << "case FN_" << id[i].name << ": //Number Function" << endl << "break;" << endl; + break; + case ID_TYPE_FN_STR: + output_line += "ID_TYPE_FN_STR);"; + f2 << fn_line << endl; + f3 << "case FN_" << id[i].name << ": //String Function" << endl << "break;" << endl; + break; + case ID_TYPE_SUB: + output_line += "ID_TYPE_SUB);"; + f2 << fn_line << endl; + f3 << "case FN_" << id[i].name << ": //Sub Procedure" << endl << "break;" << endl; + break; + default: + continue; + } + f << output_line << endl; + output_line = ""; + for(int n = 0; n < id[i].num_args; n++) + { + fn_line = "#define " + StringToUpper(id[i].name + "_" + id[i].fn_arg[n]) + " "; + + output_line = "add_embedded_arg(\"" + id[i].fn_arg[n] + "\", "; + switch(id[i].fn_arg_type[n]) + { + case ID_TYPE_NUM: + output_line += "ID_TYPE_NUM);"; + //fn_line += "num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].nid_value[0].value[0]"; + fn_line += "num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].nid_value[0].value[ num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]"; + break; + case ID_TYPE_BYREF_NUM: + output_line += "ID_TYPE_BYREF_NUM);"; + fn_line += "num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].nid_value[0].value[ num_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]"; + break; + case ID_TYPE_STR: + output_line += "ID_TYPE_STR);"; + fn_line += "str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].sid_value[0].value[ str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]"; + break; + case ID_TYPE_BYREF_STR: + output_line += "ID_TYPE_BYREF_STR);"; + fn_line += "str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].sid_value[0].value[ str_var[" + rc_intToString(id[i].fn_arg_vec[n]) + "].byref_offset ]"; + break; + } + f2 << fn_line << endl; + f << output_line << endl; + } + + } + f.close(); + f2.close(); + f3.close(); + cout << "rcbasic_dev file was created" << endl; +} + +bool rcbasic_embedded() +{ + int current_file = 0; + string line = ""; + + while( getline(rcbasic_file, line) ) + { + cout << "line " << rcbasic_program.top().line_number << ": " << rcbasic_file.tellg() << " -> " << line << endl; + //rcbasic_program.top().line_position = rcbasic_file.tellg(); + if(!rc_eval_embedded(line)) + { + cout << "Error on Line " << rcbasic_program.top().line_number << ": " << rc_getError() << endl; + return false; + } + rcbasic_program.top().line_number++; + } + + cout << endl << "VM Code" << endl << "---------------------" << endl; + debug_output_VMASM(); + return true; +} + +void rcbasic_clean() +{ + if(rcbasic_file.is_open()) + rcbasic_file.close(); + +} + +//a file with functions to add to rcbasic +void rcbasic_dev(string dev_input_file) +{ + rcbasic_dev_init(); + + if(rcbasic_loadProgram(dev_input_file)) + { + rcbasic_embedded(); + rcbasic_export_dev(); + rcbasic_clean(); + } +} + +void rcbasic_output_debug_info() +{ + fstream f("rcbasic.dbgs", fstream::out | fstream::trunc); + + for(int i = rcbasic_user_var_start; i < id.size(); i++) + { + switch(id[i].type) + { + case ID_TYPE_NUM: + f << "N " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_ARR_NUM: + f << "AN " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_BYREF_NUM: + f << "BN " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_STR: + f << "S " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_ARR_STR: + f << "AS " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_BYREF_STR: + f << "BS " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_USER: + f << "U " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_USER_NUM: + f << "UN " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_USER_NUM_ARRAY: + f << "UNA " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_USER_STR: + f << "US " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + case ID_TYPE_USER_STR_ARRAY: + f << "USA " << id[i].scope << " " << id[i].name << " " << id[i].vec_pos << "\n"; + break; + } + } + + f.close(); + + f.open("rcbasic.dbgi", fstream::out | fstream::trunc); + + for(int i = 0; i < inc_files.size(); i++) + { + f << inc_files[i] << "\n"; + } + + f.close(); +} + +int main(int argc, char * argv[]) +{ + string line = ""; + + //rcbasic_dev("embedded_functions.bas"); return 0; + + string rc_filename = "";// = "tst.bas"; + + bool clean_after_build = false; + + //DEBUG START + rc_filename = "/home/n00b/Projects/tst/test_types.bas"; + //DEBUG END + + if(argc > 1) + rc_filename = argv[1]; + + string cmd_arg = ""; + for(int i = 1; i < argc; i++) + { + cmd_arg = (string)argv[i]; + + if(cmd_arg.substr(0,1).compare("-") != 0) + rc_filename = cmd_arg; + + if(cmd_arg.compare("--debug")==0) + { + cout << "DEBUG MODE" << endl; + rcbasic_build_debug = true; + } + else if(cmd_arg.compare("--no-presets")==0) + { + cout << "DISABLE PRESETS" << endl; + enable_presets = false; + } + else if(cmd_arg.compare("--no-clean")==0) + { + clean_after_build = false; + } + } + + if(rc_filename.compare("--version")==0) + { + cout << "RCBASIC Compiler v4.0a" << endl; + return 0; + } + + //rc_filename = "tst.bas"; + + cout << "Source: " << rc_filename << endl; + + string cbc_file = rcbasic_build_debug ? "debug.cbc" : rc_filename.substr(0, rc_filename.find_last_of(".")) + ".cbc"; + if(is_file_exist(cbc_file.c_str())) + remove(cbc_file.c_str()); + + if(is_file_exist("rcbasic.dbgs")) + remove("rcbasic.dbgs"); + + if(is_file_exist("rcbasic.dbgi")) + remove("rcbasic.dbgi"); + + if(rc_filename.compare("")==0) + return 0; + + rcbasic_init(); + + rcbasic_user_var_start = id.size(); + + if(rc_filename.find_first_of(".") == string::npos) + { + cout << "file must have extension" << endl; + return 0; + } + + //if(rcbasic_loadProgram("tst.bas")) + if(rcbasic_loadProgram(rc_filename)) + { + if(!rcbasic_compile()) + { + cout << "Compile Failed" << endl; + rcbasic_clean(); + return 0; + } + else if(current_block_state != BLOCK_STATE_MAIN) + { + switch(current_block_state) + { + case BLOCK_STATE_DO: + cout << "Compile Error: Failed to close DO loop" << endl; + break; + case BLOCK_STATE_WHILE: + cout << "Compile Error: Failed to close WHILE loop" << endl; + break; + case BLOCK_STATE_FOR: + cout << "Compile Error: Failed to close FOR loop" << endl; + break; + case BLOCK_STATE_FUNCTION: + cout << "Compile Error: Failed to close FUNCTION" << endl; + break; + case BLOCK_STATE_SUB: + cout << "Compile Error: Failed to close SUB" << endl; + break; + case BLOCK_STATE_SELECT: + cout << "Compile Error: Failed to close SELECT" << endl; + break; + case BLOCK_STATE_IF: + cout << "Compile Error: Failed to close IF" << endl; + break; + case BLOCK_STATE_TYPE: + cout << "Compile Error: Failed to close TYPE" << endl; + break; + } + cout << "Compile Failed" << endl; + return 0; + } + else + rcbasic_clean(); + + //Debug + //return 0; + + //for(int i = 0; i < vm_asm.label.size(); i++) + // cout << vm_asm.label[i].label_name << " = " << vm_asm.label[i].label_address << endl; + + //cout << "for_loop = " << max_for_count << endl; + //cout << "max_n = " << max_n_reg << endl; + //cout << "max_s = " << max_s_reg << endl; + //cout << "n_stack_size = " << vm_asm.max_n_stack_count << endl; + //cout << "s_stack_size = " << vm_asm.max_s_stack_count << endl; + + //n_count + //s_count + //n_stack_count + //s_stack_count + //loop_stack_count + //numID_count + //strID_count + //label_count + //labels + + if(rcbasic_build_debug) + rcbasic_output_debug_info(); + + rcbasic_output_debug_info(); + + fstream f("main.rc_data", fstream::trunc | fstream::out); + f << max_n_reg << endl; + f << max_s_reg << endl; + f << max_u_reg << endl; + f << vm_asm.max_n_stack_count << endl; + f << vm_asm.max_s_stack_count << endl; + f << vm_asm.max_u_stack_count << endl; + f << max_for_count << endl; + f << num_id_count << endl; + f << str_id_count << endl; + f << usr_id_count << endl; + f << vm_asm.label.size() << endl; + for(int i = 0; i < vm_asm.label.size(); i++) + f << vm_asm.label[i].label_name << " " << vm_asm.label[i].label_address << " " << vm_asm.label[i].label_segment << endl; + f.close(); + + rc_cbc_assembler::rc_assemble(cbc_file, clean_after_build); + } + else + { + cout << "Could not load program" << endl; + return 0; + } + + cout << endl << "Compiled Successfully" << endl << endl << endl; //skip 3 lines so that start of program is not right below this line + + return 0; + + while(getline(cin, line)) + { + rc_eval(line); + } + return 0; +} diff --git a/rcbasic_build/parser.h b/rcbasic_build/parser.h new file mode 100644 index 0000000..00b4dc8 --- /dev/null +++ b/rcbasic_build/parser.h @@ -0,0 +1,6079 @@ +#ifndef PARSER_H_INCLUDED +#define PARSER_H_INCLUDED + +#include "tokenizer.h" +#include "identifier.h" +#include "rc_global.h" +#include "constants.h" +#include + +using namespace std; + +int max_for_count = 0; + +//vm registers +int max_n_reg = 0; +int max_s_reg = 0; +int max_u_reg = 0; +int n_reg = 0; +int s_reg = 0; +int u_reg = 0; + +//expression result +string expr_result = ""; +bool type_delete_flag = false; +string type_delete_arg = ""; + +bool pre_parse(int start_token, int end_token, int pp_flags = 0, bool eval_udt = false); //puts number and string values and variables inside number and string registers +//void getBlock(int& start_block, int& end_block); //gets the start and end index of the next block to evaluate (first and last token if there isnt a block left to evaluate +bool eval_pow(int start_block, int end_block); +bool eval_muldiv(int start_block, int end_block); //MOD operator is also evaluated in this function +bool eval_addsub(int start_block, int end_block); +bool eval_tokens(); //evaluates the tokens and generates vm_asm opcodes + +vector n_tmp; +vector s_tmp; +vector u_tmp; + + +void inc_n(int x) +{ + n_reg += x; + if( (n_reg+1) > max_n_reg) + max_n_reg = n_reg + 1; +} + +void inc_s(int x) +{ + s_reg += x; + if( (s_reg+1) > max_s_reg) + max_s_reg = s_reg + 1; +} + +void inc_u(int x) +{ + u_reg += x; + if( (u_reg+1) > max_u_reg) + max_u_reg = u_reg + 1; +} + +void debug_output_VMASM() +{ + for(int i = 0; i < vm_asm.vm_code.size(); i++) + cout << vm_asm.vm_code[i] << endl; +} + +void clear_asm() +{ + vm_asm.clear(); +} + +//end block will be set to -1 if a block was opened but wasn't closed +void getBlock(int start_token, int end_token, int& start_block, int& end_block) +{ + start_block = start_token; //start_block is set to 0, if there is no block started it will automatically start at the first token + //end_block = token.size()-1; //end_block is set to the last token, if there is no block started or ended then it will be the last token + + if(end_token > 0) + end_block = end_token; + else + end_block = token.size()-1; + + //this loop will go through every token until it finds a start_block and end_block + for(int i = start_token; i <= end_token; i++) + { + //sets the start_block to the last open block token it discovers + if(token[i].compare("")==0 || token[i].compare("")==0 || token[i].compare("")==0) + start_block = i; + + //if an ending block was encountered and it matches the current start block then the current end_block will be set to the current token + if( (token[i].compare("")==0 && token[start_block].compare("")==0) || + (token[i].compare("")==0 && token[start_block].compare("")==0) || + (token[i].compare("")==0 && token[start_block].compare("")==0)) + { + end_block = i; + + //put a ! at the beginning of the start and end block tokens so that they won't be evaluated the next time this function is called + token[start_block] = "!" + token[start_block]; + token[end_block] = "!" + token[end_block]; + + return; + } + //if there is a ending block discovered that did not have a matching start block then we set end_block to -1 and set an error message + else if(token[i].compare("")==0 || token[i].compare("")==0 || token[i].compare("")==0) + { + if(token[i].compare("")==0) + rc_setError("Found \")\" without \"(\""); + else if(token[i].compare("")==0) + rc_setError("Found \"]\" without \"[\""); + else if(token[i].compare("")==0) + rc_setError("Found \"}\" without \"{\""); + end_block = -1; + return; + } + } + //if start_block is a bracket and the closing bracket was not found before the end of the loop then end_block is set to -1 and we set an error message + if(token[start_block].compare("")==0) + { + rc_setError("Found \"(\" without \")\""); + end_block = -1; + } + else if(token[start_block].compare("")==0) + { + rc_setError("Found \"[\" without \"]\""); + end_block = -1; + } + else if(token[start_block].compare("")==0) + { + rc_setError("Found \"{\" without \"}\""); + end_block = -1; + } + +} + +//This function checks to see if a token can be exempt from the token check that eval functions do +bool token_exemption(int i) +{ + if(token[i].compare("!")==0 || token[i].compare("!")==0 || + token[i].compare("!")==0 || token[i].compare("!")==0 || + token[i].compare("!")==0 || token[i].compare("!")==0) + return true; + return false; +} + +//This function will clear every token from the first operand to the second operand and set the start operand token to solution +void set_op_solution(int start_op, int end_op, string solution) +{ + for(int i = start_op; i <= end_op; i++) + { + if(!token_exemption(i)) + token[i] = ""; + } + token[start_op] = solution; +} + +void getRegInfo(string r_reg, int &arg_type, int &arg_utype) +{ + for(int i = 0; i < resolveID_id_reg.size(); i++) + { + if(resolveID_id_reg[i].compare(r_reg)==0) + { + arg_type = resolveID_id_type[i]; + arg_utype = resolveID_id_ut_index[i]; + return; + } + } + + if(r_reg.substr(0,1).compare("s")==0) + { + arg_type = ID_TYPE_STR; + arg_utype = 0; + } + else + { + arg_type = ID_TYPE_NUM; + arg_utype = 0; + } + + return; +} + +bool eval_pow(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + + //cout << "debug_POW " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && token[i].compare("")!=0 && (op_flag == 0 || op_flag == 2)) + { + switch(op_flag) + { + case 0: + operand1 = token[i]; + //cout << "op1 = " << operand1 << endl; + op1_index = i; + op_flag = 1; + break; + case 2: + operand2 = token[i]; + //cout << "op2 = " << operand2 << endl; + op2_index = i; + op_flag = 3; + break; + } + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for exponent operation"); + return false; + } + op_flag = 2; + } + else if(token[i].compare("")!=0) + { + //cout << "reset -- " << token[i] << endl; + op_flag = 0; + } + + if(op_flag==3) + { + if(operand1.substr(0,1).compare("n")!=0 || operand2.substr(0,1).compare("n")!=0) + { + rc_setError("Expected number operand for exponent operation"); + return false; + } + vm_asm.push_back("pow " + operand1 + " " + operand2); + set_op_solution(op1_index, op2_index, operand1); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for exponent operation"); + return false; + } + + return true; +} + +bool eval_muldiv(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + int operation = 0; //0 - mul, 1 - div, 2 - mod + + //cout << "debug_MDM " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("
")!=0 && + token[i].compare("")!=0 && + (op_flag == 0 || op_flag == 2)) + { + switch(op_flag) + { + case 0: + operand1 = token[i]; + //cout << "op1 = " << operand1 << endl; + op1_index = i; + op_flag = 1; + break; + case 2: + operand2 = token[i]; + op2_index = i; + op_flag = 3; + break; + } + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for mul/div operation"); + return false; + } + op_flag = 2; + operation = 0; + } + else if(token[i].compare("
")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for mul/div operation"); + return false; + } + op_flag = 2; + operation = 1; + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for mul/div operation"); + return false; + } + op_flag = 2; + operation = 2; + } + else if(token[i].compare("")!=0) + { + op_flag = 0; + } + + if(op_flag==3) + { + if(operand1.substr(0,1).compare("n")!=0 || operand2.substr(0,1).compare("n")!=0) + { + rc_setError("Expected number operand for mul/div operation"); + return false; + } + switch(operation) + { + case 0: + vm_asm.push_back("mul " + operand1 + " " + operand2); + break; + case 1: + vm_asm.push_back("div " + operand1 + " " + operand2); + break; + case 2: + vm_asm.push_back("mod " + operand1 + " " + operand2); + break; + } + set_op_solution(op1_index, op2_index, operand1); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for mul/div operation"); + return false; + } + + return true; +} + +bool eval_addsub(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + int operation = 0; //0 - add, 1 - sub + + //cout << "\ndebug_AS " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + //output_tokens(); + //cout << endl << "^^^^^^^^^^^^^^" << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //cout << "hello: " << token[i] << endl; + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + (op_flag == 0 || op_flag == 2)) + { + switch(op_flag) + { + case 0: + operand1 = token[i]; + //cout << "!!op1 = " << operand1 << endl; + op1_index = i; + op_flag = 1; + break; + case 2: + operand2 = token[i]; + //cout << "!!op2 = " << operand1 << endl; + op2_index = i; + op_flag = 3; + break; + } + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for add/sub operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 0; + + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for add/sub operation"); + return false; + } + op_flag = 2; + operation = 1; + } + else if(token[i].compare("")!=0) + { + op_flag = 0; + } + + if(op_flag==3) + { + switch(operation) + { + case 0: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("add " + operand1 + " " + operand2); + else if(operand1.substr(0,1).compare("s")==0 && operand2.substr(0,1).compare("s")==0) + vm_asm.push_back("add$ " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for add operation: " + operand1 + ", " + operand2); + return false; + } + break; + case 1: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("sub " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for add operation"); + return false; + } + break; + } + set_op_solution(op1_index, op2_index, operand1); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for add/sub operation"); + return false; + } + + return true; +} + +bool eval_bitshift(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + int operation = 0; //0 - add, 1 - sub + + //cout << "\ndebug_BS " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + //output_tokens(); + //cout << endl << "^^^^^^^^^^^^^^" << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //cout << "hello: " << token[i] << endl; + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + (op_flag == 0 || op_flag == 2)) + { + switch(op_flag) + { + case 0: + operand1 = token[i]; + //cout << "!!op1 = " << operand1 << endl; + op1_index = i; + op_flag = 1; + break; + case 2: + operand2 = token[i]; + //cout << "!!op2 = " << operand1 << endl; + op2_index = i; + op_flag = 3; + break; + } + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for add/sub operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 0; + + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for add/sub operation"); + return false; + } + op_flag = 2; + operation = 1; + } + else if(token[i].compare("")!=0) + { + op_flag = 0; + } + + if(op_flag==3) + { + switch(operation) + { + case 0: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("shl " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for shl operation"); + return false; + } + break; + case 1: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("shr " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for shr operation"); + return false; + } + break; + } + set_op_solution(op1_index, op2_index, operand1); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for add/sub operation"); + return false; + } + + return true; +} + +bool eval_cmp(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + int operation = 0; //0 - add, 1 - sub + + //cout << "\ndebug_AS " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + //output_tokens(); + //cout << endl << "^^^^^^^^^^^^^^" << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //cout << "hello: " << token[i] << endl; + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + (op_flag == 0 || op_flag == 2)) + { + switch(op_flag) + { + case 0: + operand1 = token[i]; + //cout << "!!op1 = " << operand1 << endl; + op1_index = i; + op_flag = 1; + break; + case 2: + operand2 = token[i]; + //cout << "!!op2 = " << operand1 << endl; + op2_index = i; + op_flag = 3; + break; + } + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for less operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 0; + + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for less/equal operation"); + return false; + } + op_flag = 2; + operation = 1; + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for greater operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 2; + + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for greater/equal operation"); + return false; + } + op_flag = 2; + operation = 3; + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for equal operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 4; + + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for not equal operation"); + return false; + } + op_flag = 2; + operation = 5; + } + else if(token[i].compare("")!=0) + { + op_flag = 0; + } + + if(op_flag==3) + { + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("cmp " + operand1 + " " + operand2); + else if(operand1.substr(0,1).compare("s")==0 && operand2.substr(0,1).compare("s")==0) + vm_asm.push_back("cmp$ " + operand1 + " " + operand2); + else + { + rc_setError("Mismatch types in comparison operation"); + return false; + } + string solution = "n" + rc_intToString(n_reg); + inc_n(1); + switch(operation) + { + case 0: + vm_asm.push_back("mov " + solution + " %LESS_FLAG"); + break; + case 1: + vm_asm.push_back("mov " + solution + " %LESS_EQUAL_FLAG"); + break; + case 2: + vm_asm.push_back("mov " + solution + " %GREATER_FLAG"); + break; + case 3: + vm_asm.push_back("mov " + solution + " %GREATER_EQUAL_FLAG"); + break; + case 4: + vm_asm.push_back("mov " + solution + " %EQUAL_FLAG"); + break; + case 5: + vm_asm.push_back("mov " + solution + " %NOT_EQUAL_FLAG"); + break; + } + set_op_solution(op1_index, op2_index, solution); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for add/sub operation"); + return false; + } + + return true; +} + +bool eval_andor(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + int operation = 0; //0 - add, 1 - sub + + //cout << "\ndebug_AND " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + //output_tokens(); + //cout << endl << "^^^^^^^^^^^^^^" << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //cout << "hello: " << token[i] << endl; + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + token[i].compare("")!=0 && + (op_flag == 0 || op_flag == 2)) + { + switch(op_flag) + { + case 0: + operand1 = token[i]; + //cout << "!!op1 = " << operand1 << endl; + op1_index = i; + op_flag = 1; + break; + case 2: + operand2 = token[i]; + //cout << "!!op2 = " << operand1 << endl; + op2_index = i; + op_flag = 3; + break; + } + } + else if(token[i].compare("")==0) + { + //cout << "AND OPERATION" << endl; + if(op_flag != 1) + { + rc_setError("Missing operand for and operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 0; + + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for or operation"); + return false; + } + op_flag = 2; + operation = 1; + } + else if(token[i].compare("")==0) + { + if(op_flag != 1) + { + rc_setError("Missing operand for xor operation : " + rc_intToString(op_flag) ); + return false; + } + op_flag = 2; + operation = 2; + + } + else if(token[i].compare("")!=0) + { + op_flag = 0; + } + + if(op_flag==3) + { + switch(operation) + { + case 0: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("and " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for and operation"); + return false; + } + break; + case 1: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("or " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for or operation"); + return false; + } + break; + case 2: + if(operand1.substr(0,1).compare("n")==0 && operand2.substr(0,1).compare("n")==0) + vm_asm.push_back("xor " + operand1 + " " + operand2); + else + { + rc_setError("Incompatible operands for xor operation"); + return false; + } + break; + } + set_op_solution(op1_index, op2_index, operand1); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for add/sub operation"); + return false; + } + + return true; +} + +bool eval_not(int start_block, int end_block) +{ + int op_flag = 0; + string operand1 = ""; + string operand2 = ""; + + int op1_index = 0; + int op2_index = 0; + int operation = 0; //0 - add, 1 - sub + + //cout << "\ndebug_AS " << start_block << " " << end_block << endl; + //cout << "t_size" << token.size() << endl; + //output_tokens(); + //cout << endl << "^^^^^^^^^^^^^^" << endl; + + for(int i = start_block; i <= end_block; i++) + { + if(token_exemption(i)) + { + //cout << "hello: " << token[i] << endl; + //op_flag = 0; + continue; + } + + if(token[i].compare("")!=0 && + token[i].compare("")!=0 && + op_flag == 1) + { + + operand1 = token[i]; + //cout << "!!op1 = " << operand1 << endl; + op2_index = i; + op_flag = 2; + } + else if(token[i].compare("")==0) + { + op1_index = i; + op_flag = 1; + } + else if(token[i].compare("")!=0) + { + op_flag = 0; + } + + if(op_flag==2) + { + if(operand1.substr(0,1).compare("n")==0) + vm_asm.push_back("not " + operand1); + else + { + rc_setError("Incompatible operands for and operation"); + return false; + } + set_op_solution(op1_index, op2_index, operand1); + op_flag = 0; + i = start_block-1; + } + } + + if(op_flag == 2) + { + rc_setError("Expected operand for add/sub operation"); + return false; + } + + return true; +} + +//still need to store negative numbers properly +#define PP_FLAG_NONE 0 +#define PP_FLAG_ARRAY 1 + +int getArrayObjStart(int arg_id) +{ + string start_arg = "n" + rc_intToString(n_reg); + inc_n(1); + vm_asm.push_back("mov " + start_arg + " 0"); + if(id[arg_id].type == ID_TYPE_ARR_NUM) + { + switch(id[arg_id].num_args) + { + case 1: + vm_asm.push_back("obj_num1 !" + rc_intToString(id[arg_id].vec_pos) + " " + start_arg); + break; + case 2: + vm_asm.push_back("obj_num2 !" + rc_intToString(id[arg_id].vec_pos) + " " + start_arg + " " + start_arg); + break; + case 3: + vm_asm.push_back("obj_num3 !" + rc_intToString(id[arg_id].vec_pos) + " " + start_arg + " " + start_arg + " " + start_arg); + break; + } + int obj_n = n_reg; + inc_n(1); + vm_asm.push_back("obj_get n" + rc_intToString(obj_n)); + return obj_n; + } + else if(id[arg_id].type == ID_TYPE_ARR_STR) + { + switch(id[arg_id].num_args) + { + case 1: + vm_asm.push_back("obj_str1 !" + rc_intToString(id[arg_id].vec_pos) + " " + start_arg); + break; + case 2: + vm_asm.push_back("obj_str2 !" + rc_intToString(id[arg_id].vec_pos) + " " + start_arg + " " + start_arg); + break; + case 3: + vm_asm.push_back("obj_str3 !" + rc_intToString(id[arg_id].vec_pos) + " " + start_arg + " " + start_arg + " " + start_arg); + break; + } + int obj_s = s_reg; + inc_s(1); + vm_asm.push_back("obj_get$ s" + rc_intToString(obj_s)); + return obj_s; + } + + return 0; + +} + + +bool pre_parse(int start_token = 0, int end_token = -1, int pp_flags, bool eval_udt) +{ + + if(end_token == -1) + { + end_token = token.size(); + } + + int n_flag = 0; // id num ] ) } , + string n = ""; + string s = ""; + string u = ""; + int expr_id = -1; + string sdata = ""; + + for(int i = start_token; i <= end_token; i++) + { + if(token[i].substr(0,5).compare("")==0) + { + //cout << "WISHING FOR A MIRACLE" << endl; + n = "n" + rc_intToString(n_reg); + vm_asm.push_back("mov " + n + " " + token[i].substr(5)); + token[i] = n; + inc_n(1); + } + else if(token[i].substr(0,8).compare("")==0) + { + //store strings in data + sdata = token[i].substr(8); + int sdata_addr = data_segment.size(); + for(int n = 0; n < sdata.length(); n++) + { + data_segment.push_back(sdata[n]); + } + data_segment.push_back('\0'); + string token_replace = "s" + rc_intToString(s_reg); + inc_s(1); + vm_asm.push_back("mov$ " + token_replace + " @" + rc_intToString(sdata_addr)); + token[i] = token_replace; + } + else if(token[i].substr(0,4).compare("")==0) + { + //cout << "ID: " << token[i].substr(4) << endl; + //more needs to be done here + n = "n" + rc_intToString(n_reg); + s = "s" + rc_intToString(s_reg); + u = "u" + rc_intToString(u_reg); + + expr_id = getIDInScope_ByIndex(token[i].substr(4)); + + //cout << "expr = " << expr_id << endl; + //cout << "TYPE: " << id[expr_id].type << endl << endl; + + bool is_udt_member = false; + + if(i > 0) + if(token[i-1].compare("")==0) + is_udt_member = true; + + if(is_udt_member) + continue; + + + if(expr_id < 0) + { + //rc_setError(token[i].substr(4) + " was not found in this scope+: " + current_scope); + rc_setError(token[i].substr(4) + " was not found in this scope"); + //output_vars(); + return false; + } +// else if(id[expr_id].type == ID_TYPE_BYREF_NUM) +// { +// vm_asm.push_back("mov " + n + " !" + rc_intToString(id[expr_id].vec_pos)); +// resolveID_id_reg.push_back(n); +// resolveID_id_type.push_back(id[expr_id].type); +// resolveID_id_ut_index.push_back(id[expr_id].type_index); +// token[i] = n; +// inc_n(1); +// } + else if(id[expr_id].type == ID_TYPE_NUM) + { + //cout << endl << "COME ON: " << id[expr_id].name << endl; + vm_asm.push_back("mov " + n + " !" + rc_intToString(id[expr_id].vec_pos)); + resolveID_id_reg.push_back(n); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + token[i] = n; + inc_n(1); + } + else if(id[expr_id].type == ID_TYPE_STR) + { + vm_asm.push_back("mov$ " + s + " !" + rc_intToString(id[expr_id].vec_pos)); + resolveID_id_reg.push_back(s); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + token[i] = s; + inc_s(1); + } + else if( (id[expr_id].type == ID_TYPE_BYREF_NUM || id[expr_id].type == ID_TYPE_BYREF_STR) && pp_flags == PP_FLAG_ARRAY) + { + //cout << "found array: " << id[expr_id].name << endl << endl; + int s_scope = 0; + int arr_token_start = i; + int arr_token_end = i; + string args[512]; + int num_args = 0; + + int p_scope = 0; + + if( (i+1) <= end_token) + { + if(token[i+1].compare("!")==0) + { + s_scope = 1; + for(i += 2; (i <= end_token) && (s_scope != 0); i++) + { + if(token[i].compare("!")==0) + { + s_scope--; + if(s_scope == 0) + { + num_args++; + arr_token_end = i; + } + } + else if(token[i].compare("!")==0) + s_scope++; + else if(token[i].compare("!")==0) + num_args++; + else if(token[i].substr(0,1).compare("n")==0) + args[num_args] = token[i]; + else if(token[i].compare("!")==0) + p_scope++; + else if(token[i].compare("!")==0) + p_scope--; + else if(token[i].compare("")!=0) + { + rc_setError("Expected number"); + return false; + } + } + if(p_scope > 0) + { + rc_setError("Parenthesis Block was not closed"); + return false; + } + else if(p_scope < 0) + { + rc_setError("Parenthesis Block was not opened"); + return false; + } + if(s_scope != 0) + { + rc_setError("Expected closing ]"); + return false; + } + } + } + + if(num_args > 1) + { + rc_setError("In " + id[expr_id].name + " Expected 0 to 1 dimensions and found " + rc_intToString(num_args)); + return false; + } + + if(id[expr_id].type == ID_TYPE_BYREF_NUM && num_args == 0) + { + vm_asm.push_back("mov " + n + " !" + rc_intToString(id[expr_id].vec_pos)); + resolveID_id_reg.push_back(n); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + token[i] = n; + inc_n(1); + continue; + } + else if(id[expr_id].type == ID_TYPE_BYREF_STR && num_args == 0) + { + vm_asm.push_back("mov$ " + s + " !" + rc_intToString(id[expr_id].vec_pos)); + resolveID_id_reg.push_back(s); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + token[i] = s; + inc_s(1); + continue; + } + + + + if(args[0].substr(0,1).compare("n")!=0) + { + rc_setError("Invalid number of args in array"); + return false; + } + + + string token_replace = ""; + + if(id[expr_id].type == ID_TYPE_BYREF_NUM) + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_num1 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0]); + token_replace = "n" + rc_intToString(n_reg); + inc_n(1); + vm_asm.push_back("obj_get " + token_replace); + } + else + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_str1 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0]); + token_replace = "s" + rc_intToString(s_reg); + inc_s(1); + vm_asm.push_back("obj_get$ " + token_replace); + } + + + resolveID_id_reg.push_back(token_replace); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + + for(int p = arr_token_start; p <= arr_token_end; p++) + token[p] = ""; + + if(token_replace.compare("")==0) + { + rc_setError("%%could not resolve array " + id[expr_id].name); + return false; + } + + token[arr_token_start] = token_replace; + + //cout << "the end of array" << endl; + + } + else if( ID_TYPE_USER_ALL(expr_id) && eval_udt ) + { + cout << "-Parsing User Variable: " << id[expr_id].name << endl; + cout << "----------------------------------------------- : " << eval_udt << endl; + + bool udt_id_init = true; + + string tmp_scope = id[expr_id].scope; + + + for(int t = i; t < token.size(); t++) + { + try + { + cout << t << ":" << token.at(t) << endl; + } + catch(out_of_range& e) + { + cout << "Token Out of Range Error: " << e.what() << endl; + } + } + + + int tmp_id = 0; + bool has_child = false; + + + for(int t = i; t <= end_token; t++) + { + + if(token[t].substr(0,4).compare("")==0) + { + cout << "FIGURE IT OUT: " << t << endl; + string args[3]; + int arg_count = 0; + string full_id = token[t].substr(4); + token[t] = ""; + tmp_id = getIDInScope_ByIndex_TypeMatch(full_id, tmp_scope); + //cout << "\ntmp_id = " << tmp_id << endl; + + if(tmp_id < 0) + { + rc_setError(tmp_scope.substr(5) + " does not have member [" + full_id + "]"); + return false; + } + + cout << "Scope = " << tmp_scope << " ID = " << full_id << " -- " << tmp_id << endl << endl; + + tmp_scope += "." + full_id; + + + //get arguments (ie. the dimensions of an array + int t2 = t+1; + + if(t2 < end_token) + { + int arr_scope = 0; + if(token[t2].compare("!")==0) + { + token[t2] = ""; + args[0] = ""; + args[1] = ""; + args[2] = ""; + arg_count = 0; + arr_scope = 1; + t2++; + cout << "T2 = " << t2 << endl << endl; + + for(; t2 <= end_token; t2++) + { + //cout << "DBG ARR: " << t2 << ", " << end_token << " : " << token[t2] << endl; + if(token[t2].compare("!")==0) + arr_scope--; + else if(token[t2].compare("!")==0) + arr_scope++; + else if(token[t2].compare("!")==0) + arg_count++; + else if(token[t2].substr(0,1).compare("n")==0) + { + if(args[arg_count].compare("")==0) + args[arg_count] = token[t2]; + else + { + rc_setError("Error parsing array dimension: " + args[arg_count] + " :: " + token[t2] + " -- " + rc_intToString(t2) + ", " + rc_intToString(arg_count)); + return false; + } + } + + token[t2] = ""; + + if(arg_count >= 3) + { + rc_setError("Too many dimensions in array"); + return false; + } + + if(arr_scope == 0) + break; + + } + + if(arr_scope > 0) + { + rc_setError("Expected ]] in expression: " + rc_intToString(arr_scope)); + return false; + } + + arg_count++; + } + + } + + + has_child = false; + if((t2+1) < token.size()) + { + if(token[t2+1].compare("")==0) + { + has_child = true; + } + cout << "Has Child = " << has_child << ", " << t << ", " << t2 << endl; + } + + + if(arg_count != id[tmp_id].num_args) + { + if(!type_delete_flag) + { + rc_setError("[0]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name); + return false; + } + else + { + if(has_child) + { + rc_setError("[1]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name); + return false; + } + + arg_count = id[tmp_id].num_args; + //vm_asm.push_back("mov n" + rc_intToString(n_reg) + " 0"); + //args[0] = "n" + rc_intToString(n_reg); + //args[1] = args[0]; + //args[2] = args[0]; + //inc_n(1); + } + } + + if(type_delete_flag && (!has_child)) + { + //DO NOTHING + //cout << "NO CHILD: " << id[tmp_id].name << endl; + } + else + { + //if(type_delete_flag) + // cout << "TESTING STUFF" << endl; + + switch(arg_count) + { + case 0: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init !" + rc_intToString(id[tmp_id].vec_pos)); + else + vm_asm.push_back("obj_usr !" + rc_intToString(id[tmp_id].vec_pos)); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n !" + rc_intToString(id[tmp_id].vec_pos)); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s !" + rc_intToString(id[tmp_id].vec_pos)); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + case 1: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + else + vm_asm.push_back("obj_usr1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + case 2: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + else + vm_asm.push_back("obj_usr2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + case 3: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + else + vm_asm.push_back("obj_usr3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + } + + udt_id_init = false; + } + + + + } + else if(token[t].compare("")==0) + { + token[t] = ""; + continue; + } + else if(token[t].compare("")!=0) + { + break; + } + + } + + + //START HERE + if(type_delete_flag && (!has_child)) + { + //cout << "DELETE_VAR = " << id[tmp_id].name << endl; + type_delete_arg = "!" + rc_intToString(id[tmp_id].vec_pos); + } + else + switch(id[tmp_id].type) + { + case ID_TYPE_USER: + case ID_TYPE_BYREF_USER: + cout << "test --> " << u << ", " << id[tmp_id].name << endl; + vm_asm.push_back("obj_usr_get " + u); + token[i] = u; + resolveID_id_reg.push_back(token[i]); + resolveID_id_type.push_back(id[tmp_id].type); + resolveID_id_ut_index.push_back(id[tmp_id].type_index); + resolveID_id_vec_pos.push_back(tmp_id); + inc_u(1); + break; + case ID_TYPE_USER_NUM: + vm_asm.push_back("obj_usr_get " + n); + token[i] = n; + inc_n(1); + break; + case ID_TYPE_USER_STR: + vm_asm.push_back("obj_usr_get " + s); + token[i] = s; + inc_s(1); + break; + default: + break; + } + + + cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << endl; + + for(int t = 0; t < token.size(); t++) + { + try + { + cout << t << ":" << token.at(t) << endl; + } + catch(out_of_range& e) + { + cout << "Token Out of Range Error: " << e.what() << endl; + } + } + + cout << "-----------------------------------------------" << endl; + + + //for(int t = 0; t < id.size(); t++) + // if(id[t].type == ID_TYPE_USER) cout << "ID[" << id[t].name << "] SCOPE=" << id[t].scope << " -- " << id[t].vec_pos << endl; + + } + else if( (id[expr_id].type == ID_TYPE_ARR_NUM || id[expr_id].type == ID_TYPE_ARR_STR) && pp_flags == PP_FLAG_ARRAY) + { + //cout << "found array: " << id[expr_id].name << endl << endl; + int s_scope = 0; + int arr_token_start = i; + int arr_token_end = i; + string args[3]; + int num_args = 0; + + int p_scope = 0; + + if( (i+1) <= end_token) + { + if(token[i+1].compare("!")==0) + { + s_scope = 1; + for(i += 2; (i <= end_token) && (s_scope != 0); i++) + { + if(token[i].compare("!")==0) + { + s_scope--; + if(s_scope == 0) + { + num_args++; + arr_token_end = i; + } + } + else if(token[i].compare("!")==0) + s_scope++; + else if(token[i].compare("!")==0) + num_args++; + else if(token[i].substr(0,1).compare("n")==0) + args[num_args] = token[i]; + else if(token[i].compare("!")==0) + p_scope++; + else if(token[i].compare("!")==0) + p_scope--; + else if(token[i].compare("")!=0) + { + rc_setError("Expected number"); + return false; + } + } + if(p_scope > 0) + { + rc_setError("Parenthesis Block was not closed"); + return false; + } + else if(p_scope < 0) + { + rc_setError("Parenthesis Block was not opened"); + return false; + } + } + } + //cout << endl << "ID_ARRAY: " << id[expr_id].name << endl; + //cout << "NUM_ARGS_EXPECTED: " << id[expr_id].num_args << endl; + //cout << "NUM_ARGS_FOUND: " << num_args << endl; + + if(id[expr_id].isArrayArg) + { + //cout << "array arg found" << endl; + id[expr_id].isArrayArg = false; + string token_replace = ""; + if(id[expr_id].type == ID_TYPE_ARR_NUM) + { + token_replace = "n" + rc_intToString(n_reg); + inc_n(1); + vm_asm.push_back("mov_arr " + token_replace + " !" + rc_intToString(id[expr_id].vec_pos)); + + } + else + { + token_replace = "s" + rc_intToString(s_reg); + inc_s(1); + vm_asm.push_back("mov_arr$ " + token_replace + " !" + rc_intToString(id[expr_id].vec_pos)); + } + + resolveID_id_reg.push_back(token_replace); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + + for(int p = arr_token_start; p <= arr_token_end; p++) + token[p] = ""; + + token[arr_token_start] = token_replace; + continue; + } + + if(id[expr_id].num_args != num_args) + { + if(num_args == 0) + continue; + + rc_setError("In " + id[expr_id].name + " Expected " + rc_intToString(id[expr_id].num_args) + " dimensions and found " + rc_intToString(num_args)); + return false; + } + + for(int n = 0; n < id[expr_id].num_args; n++) + { + //cout << "arg " << n << ": " << args[n] << endl; + if(args[n].substr(0,1).compare("n")!=0) + { + rc_setError("Invalid number of args in array"); + return false; + } + } + + string token_replace = ""; + + switch(num_args) + { + + case 1: + if(id[expr_id].type == ID_TYPE_ARR_NUM) + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_num1 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0]); + token_replace = "n" + rc_intToString(n_reg); + inc_n(1); + vm_asm.push_back("obj_get " + token_replace); + } + else + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_str1 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0]); + token_replace = "s" + rc_intToString(s_reg); + inc_s(1); + vm_asm.push_back("obj_get$ " + token_replace); + } + break; + case 2: + if(id[expr_id].type == ID_TYPE_ARR_NUM) + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_num2 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0] + " " + args[1]); + token_replace = "n" + rc_intToString(n_reg); + inc_n(1); + vm_asm.push_back("obj_get " + token_replace); + } + else + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_str2 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0] + " " + args[1]); + token_replace = "s" + rc_intToString(s_reg); + inc_s(1); + vm_asm.push_back("obj_get$ " + token_replace); + } + break; + case 3: + if(id[expr_id].type == ID_TYPE_ARR_NUM) + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_num3 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + token_replace = "n" + rc_intToString(n_reg); + inc_n(1); + vm_asm.push_back("obj_get " + token_replace); + } + else + { + //vm_asm.push_back("clear_obj"); + vm_asm.push_back("obj_str3 !" + rc_intToString(id[expr_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + token_replace = "s" + rc_intToString(s_reg); + inc_s(1); + vm_asm.push_back("obj_get$ " + token_replace); + } + break; + default: + rc_setError("Invalid number of dimensions in array"); + return false; + } + + resolveID_id_reg.push_back(token_replace); + resolveID_id_type.push_back(id[expr_id].type); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + + for(int p = arr_token_start; p <= arr_token_end; p++) + token[p] = ""; + + if(token_replace.compare("")==0) + { + rc_setError("Could not resolve array " + id[expr_id].name); + return false; + } + + token[arr_token_start] = token_replace; + + //cout << "the end of array" << endl; + + } + else if( (id[expr_id].type == ID_TYPE_FN_NUM || id[expr_id].type == ID_TYPE_FN_STR || id[expr_id].type == ID_TYPE_FN_USER || id[expr_id].type == ID_TYPE_SUB) && pp_flags == PP_FLAG_ARRAY) + { + //cout << "FUNCTION: " << id[expr_id].name << endl; + + //output_tokens(); + //cout << "found function: " << id[expr_id].name << " " << current_block_state << endl << endl; + //cout << "fn ids = " << id[expr_id].fn_var.size() << endl; + + //push all current function ids onto stack before setting them with the expression function values +// if(isInFunctionScope) +// { +// for(int n = 0; n < id[expr_id].fn_var.size(); n++) +// { +// cout << "fid[" << n << "] = " << id[expr_id].fn_var[n].vec_str << endl; +// if(id[expr_id].fn_var[n].type == ID_TYPE_NUM || id[expr_id].fn_var[n].type == ID_TYPE_BYREF_NUM || id[expr_id].fn_var[n].type == ID_TYPE_ARR_NUM) +// { +// vm_asm.push_back("push " + id[expr_id].fn_var[n].vec_str); +// } +// else +// { +// vm_asm.push_back("push$ " + id[expr_id].fn_var[n].vec_str); +// } +// } +// +// } + //cout << "debug 1" << endl; + + int s_scope = 0; + int arr_token_start = i; + int arr_token_end = i; + string args[1024]; + args[0] = ""; + int num_args = 0; + int arg_size = 0; //this variable counts the number of tokens in a argument; used to fix multiple tokens in 1 argument (ie. abs(5 7) should not compile) + if( (i+1) <= end_token) + { + //cout << "DBG #1: " << id[expr_id].name << endl; + if(token[i+1].compare("!")==0) + { + //cout << "DBG #2" <")==0) + { + //cout << "DBG #4: " << s_scope << endl; + s_scope--; + if(s_scope == 0) + { + //num_args++; + if(num_args > 0 || args[0].compare("") != 0) + num_args++; + arr_token_end = i; + } + } + else if(token[i].compare("!")==0) + s_scope++; + else if(token[i].compare("!")==0) + { + num_args++; + arg_size = 0; + } + else if(token[i].substr(0,1).compare("n")==0 || token[i].substr(0,1).compare("s")==0 || token[i].substr(0,1).compare("u")==0 || token[i].substr(0,4).compare("")==0) + { + //cout << id[expr_id].name << "->DBG #3:" << num_args << " " << token[i] << endl; + args[num_args] = token[i]; + + arg_size++; + if(arg_size > 1) + { + rc_setError("Expected Operator in expression"); + return false; + } + } + else if(token[i].compare("")!=0) + { + rc_setError("Invalid argument in function: "+token[i]); + return false; + } + } + } + } + //cout << endl << "ID_ARRAY: " << id[expr_id].name << endl; + //cout << "NUM_ARGS_EXPECTED: " << id[expr_id].num_args << endl; + //cout << "NUM_ARGS_FOUND: " << num_args << endl; + + if(id[expr_id].num_args != num_args) + { + rc_setError("In " + id[expr_id].name + " Expected " + rc_intToString(id[expr_id].num_args) + " arguments and found " + rc_intToString(num_args)); + //rc_setError("arg[0]=" + args[0]); + //cout <<"TOEK" << endl; + output_tokens(); + return false; + } + + int resolve_index = -1; + int resolve_index2 = -1; + int resolve_id = -1; + int resolve_id2 = -1; + int arg_index = -1; + + if(StringToLower(id[expr_id].name).compare("arraydim")==0) + { + //cout << "HERES JOHNNY" << endl; + resolve_index = getResolveReg(args[0]); + if(resolve_index < 0) + { + rc_setError("Expected Identifier in ArrayDim argument: " + args[0]); + return false; + } + switch(resolveID_id_type[resolve_index]) + { + case ID_TYPE_ARR_NUM: + case ID_TYPE_BYREF_NUM: + case ID_TYPE_NUM: + expr_id = getIDInScope_ByIndex("NumberArrayDim"); + break; + case ID_TYPE_ARR_STR: + case ID_TYPE_BYREF_STR: + case ID_TYPE_STR: + expr_id = getIDInScope_ByIndex("StringArrayDim"); + break; + } + if(expr_id < 0) + { + rc_setError("ArrayDim Syntax Error"); + return false; + } + } + else if(StringToLower(id[expr_id].name).compare("arraysize")==0) + { + //cout << "HERES JOHNNY" << endl; + resolve_index = getResolveReg(args[0]); + if(resolve_index < 0) + { + rc_setError("Expected Identifier in ArraySize argument: " +args[0]); + return false; + } + switch(resolveID_id_type[resolve_index]) + { + case ID_TYPE_ARR_NUM: + case ID_TYPE_BYREF_NUM: + case ID_TYPE_NUM: + expr_id = getIDInScope_ByIndex("NumberArraySize"); + break; + case ID_TYPE_ARR_STR: + case ID_TYPE_BYREF_STR: + case ID_TYPE_STR: + expr_id = getIDInScope_ByIndex("StringArraySize"); + break; + } + if(expr_id < 0) + { + rc_setError("ArraySize Syntax Error"); + return false; + } + } + else if(StringToLower(id[expr_id].name).compare("arraycopy")==0) + { + //cout << "HERES JOHNNY" << endl; + if(num_args != 2) + { + rc_setError("ArrayCopy expects 2 arguments"); + return false; + } + + resolve_index = getResolveReg(args[0]); + resolve_index2 = getResolveReg(args[1]); + + if(resolve_index < 0 || resolve_index2 < 0) + { + rc_setError("Expected Identifier in ArrayCopy argument: " +args[0]); + return false; + } + + resolve_id = resolveID_id_vec_pos[resolve_index]; + resolve_id2 = resolveID_id_vec_pos[resolve_index2]; + + switch(resolveID_id_type[resolve_index]) + { + case ID_TYPE_ARR_NUM: + case ID_TYPE_BYREF_NUM: + case ID_TYPE_NUM: + expr_id = getIDInScope_ByIndex("NumberArrayCopy"); + if(resolveID_id_type[resolve_index2] != ID_TYPE_ARR_NUM && + resolveID_id_type[resolve_index2] != ID_TYPE_BYREF_NUM && + resolveID_id_type[resolve_index2] != ID_TYPE_NUM) + { + rc_setError("ArrayCopy argument types don't match"); + return false; + } + + if(id[resolve_id].num_args != id[resolve_id2].num_args) + { + rc_setError("ArrayCopy dimensions don't match"); + return false; + } + break; + case ID_TYPE_ARR_STR: + case ID_TYPE_BYREF_STR: + case ID_TYPE_STR: + expr_id = getIDInScope_ByIndex("StringArrayCopy"); + if(resolveID_id_type[resolve_index2] != ID_TYPE_ARR_STR && + resolveID_id_type[resolve_index2] != ID_TYPE_BYREF_STR && + resolveID_id_type[resolve_index2] != ID_TYPE_STR) + { + rc_setError("ArrayCopy argument types don't match"); + return false; + } + if(id[resolve_id].num_args != id[resolve_id2].num_args) + { + rc_setError("ArrayCopy dimensions don't match"); + return false; + } + break; + } + if(expr_id < 0) + { + rc_setError("ArrayCopy Syntax Error"); + return false; + } + } + else if(StringToLower(id[expr_id].name).compare("arrayfill")==0) + { + //cout << "HERES JOHNNY" << endl; + resolve_index = getResolveReg(args[0]); + if(resolve_index < 0) + { + rc_setError("Expected Identifier in ArrayFill argument: " + args[0]); + return false; + } + switch(resolveID_id_type[resolve_index]) + { + case ID_TYPE_ARR_NUM: + case ID_TYPE_BYREF_NUM: + case ID_TYPE_NUM: + expr_id = getIDInScope_ByIndex("NumberArrayFill"); + break; + case ID_TYPE_ARR_STR: + case ID_TYPE_BYREF_STR: + case ID_TYPE_STR: + expr_id = getIDInScope_ByIndex("StringArrayFill"); + break; + } + if(expr_id < 0) + { + rc_setError("ArrayFill Syntax Error"); + return false; + } + } + + bool local_state_is_pushed = false; //this variable checks will be set to true if the following function call is recursive + if(block_state.size() > 0) + { + if(current_scope.substr(0, ("main."+id[expr_id].name).length()).compare("main."+id[expr_id].name)==0) + { + local_state_is_pushed = true; + //cout << "DEBUG: local_state_is_pushed=" << (local_state_is_pushed ? "TRUE":"FALSE") << endl; + //push all variables that were made in current function + string tmp_type_scope = "_"; + for(uint32_t fn_var_id = current_fn_index+1; fn_var_id < id.size(); fn_var_id++) + { + switch(id[fn_var_id].type) + { + case ID_TYPE_NUM: + vm_asm.push_back("push !" + rc_intToString(id[fn_var_id].vec_pos)); + n_tmp.push_back("!" + rc_intToString(id[fn_var_id].vec_pos) ); + //cout << "push -- " << id[fn_var_id].name << endl; + break; + case ID_TYPE_STR: + vm_asm.push_back("push$ !" + rc_intToString(id[fn_var_id].vec_pos)); + s_tmp.push_back("!" + rc_intToString(id[fn_var_id].vec_pos) ); + break; + //TODO: NEED TO ADD CASE TO PUSH USER TYPES HERE + case ID_TYPE_USER: + if(id[fn_var_id].scope.substr(0, tmp_type_scope.length()).compare(tmp_type_scope)==0) + break; + + tmp_type_scope = id[fn_var_id].scope + "." + id[fn_var_id].name; + //cout << "TYPE Push: " << id[fn_var_id].name << " : SCOPE=" << tmp_type_scope << endl; + + vm_asm.push_back("push_t !" + rc_intToString(id[fn_var_id].vec_pos)); + u_tmp.push_back("!" + rc_intToString(id[fn_var_id].vec_pos) ); + break; + } + } + } + } + + + for(int n = 0; n < id[expr_id].num_args; n++) + { + //cout << "args: " << args[n] << endl; + if(args[n].substr(0,1).compare("n")!=0 && args[n].substr(0,1).compare("s")!=0 && args[n].substr(0,1).compare("u")!=0 && args[n].substr(0,4).compare("")!=0) + { + rc_setError("--Invalid number of args in function: " + args[n]); + return false; + } + + if(id[expr_id].fn_arg_type[n] == ID_TYPE_BYREF_NUM || id[expr_id].fn_arg_type[n] == ID_TYPE_BYREF_STR) + { + resolve_index = getResolveReg(args[n]); + if(args[n].substr(0,4).compare("")==0) + { + //cout << "found id: " << args[n] << " in " << id[expr_id].name << endl; + string t_replace = ""; + int arg_id = getIDInScope_ByIndex(args[n].substr(4)); + if(arg_id < 0) + { + rc_setError("Identifier was not declared in ByRef argument"); + return false; + } + if(id[arg_id].type == ID_TYPE_ARR_NUM) + { + t_replace = "n" + rc_intToString( getArrayObjStart(arg_id)); + //t_replace = "n" + rc_intToString(n_reg); + //inc_n(1); + //vm_asm.push_back("mov " + t_replace + " !" + rc_intToString(id[arg_id].vec_pos)); + + resolveID_id_reg.push_back(t_replace); + resolveID_id_type.push_back(id[arg_id].type); + resolveID_id_ut_index.push_back(id[arg_id].type_index); + resolveID_id_vec_pos.push_back(arg_id); + resolve_index = resolveID_id_reg.size()-1; + } + else if(id[arg_id].type == ID_TYPE_ARR_STR) + { + t_replace = "s" + rc_intToString( getArrayObjStart(arg_id)); + //t_replace = "s" + rc_intToString(s_reg); + //inc_s(1); + //vm_asm.push_back("mov$ " + t_replace + " !" + rc_intToString(id[arg_id].vec_pos)); + + resolveID_id_reg.push_back(t_replace); + resolveID_id_type.push_back(id[arg_id].type); + resolveID_id_ut_index.push_back(id[arg_id].type_index); + resolveID_id_vec_pos.push_back(arg_id); + resolve_index = resolveID_id_reg.size()-1; + } + else + { + rc_setError("Could not resolve Identifier in ByRef argument"); + return false; + } + } + + if(resolve_index < 0) + { + rc_setError("Expected identifier for ByRef argument"); + return false; + } + + /*arg_index = getIDInScope_ByIndex(resolveID_id_reg[resolve_index]); + + if(arg_index < 0) + { + rc_setError("Identifier " + resolveID_id_reg[resolve_index] + " was not defined in this scope"); + return false; + }*/ + + switch(id[expr_id].fn_arg_type[n]) + { + case ID_TYPE_BYREF_NUM: + if(resolveID_id_type[resolve_index] != ID_TYPE_NUM && resolveID_id_type[resolve_index] != ID_TYPE_ARR_NUM && resolveID_id_type[resolve_index] != ID_TYPE_BYREF_NUM) + { + rc_setError("Expected number identifier for argument"); + return false; + } + vm_asm.push_back("ptr !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + resolveID_id_reg[resolve_index]); + break; + case ID_TYPE_BYREF_STR: + if(resolveID_id_type[resolve_index] != ID_TYPE_STR && resolveID_id_type[resolve_index] != ID_TYPE_ARR_STR && resolveID_id_type[resolve_index] != ID_TYPE_BYREF_STR) + { + rc_setError("Expected string identifier for argument"); + return false; + } + vm_asm.push_back("ptr$ !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + resolveID_id_reg[resolve_index]); + break; + } + } + else if(id[expr_id].fn_arg_type[n] == ID_TYPE_BYREF_USER) + { + int ut_info = -1; + int ut_index = -1; + getRegInfo(args[n], ut_info, ut_index); + if(ut_index != id[expr_id].fn_arg_utype[n]) + { + rc_setError("Expected \"" + utype[id[expr_id].fn_arg_utype[n]].name + "\" identifier for ByRef argument"); + return false; + } + vm_asm.push_back("uref_ptr !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); + } + else if(id[expr_id].fn_arg_type[n] == ID_TYPE_NUM) + { + if(args[n].substr(0,1).compare("n")!=0) + { + rc_setError("Expected number expression for argument"); + return false; + } + //vm_asm.push_back("mov " + id[expr_id].fn_arg[n] + "->" + id[expr_id].fn_reg[n] + " " + args[n]); + vm_asm.push_back("mov !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); + } + else if(id[expr_id].fn_arg_type[n] == ID_TYPE_STR) + { + if(args[n].substr(0,1).compare("s")!=0) + { + rc_setError("Expected string expression for argument"); + return false; + } + //vm_asm.push_back("mov " + id[expr_id].fn_arg[n] + "->" + id[expr_id].fn_reg[n] + " " + args[n]); + vm_asm.push_back("mov$ !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); + } + else if(id[expr_id].fn_arg_type[n] == ID_TYPE_USER) + { + //TODO: NEED TO CHECK UTYPE FOR ARG + if(args[n].substr(0,1).compare("u")!=0) + { + rc_setError("Expected expression of type \"" + utype[id[expr_id].fn_arg_utype[n]].name + "\" for argument"); + return false; + } + + int ut_info = -1; + int ut_index = -1; + getRegInfo(args[n], ut_info, ut_index); + if(ut_index != id[expr_id].fn_arg_utype[n]) + { + rc_setError("Expected \"" + utype[id[expr_id].fn_arg_utype[n]].name + "\" identifier for argument"); + return false; + } + + //vm_asm.push_back("mov " + id[expr_id].fn_arg[n] + "->" + id[expr_id].fn_reg[n] + " " + args[n]); + + vm_asm.push_back("mov_type !" + rc_intToString(id[expr_id].fn_arg_vec[n]) + " " + args[n]); + } + } + + string token_replace = ""; + + if(id[expr_id].isBuiltin) + vm_asm.push_back("func !" + rc_intToString(id[expr_id].vmFunctionIndex)); + else + { + for(int n = 0; n < n_reg; n++) + { + vm_asm.push_back("push n" + rc_intToString(n)); + n_tmp.push_back("n"+rc_intToString(n)); + } + for(int n = 0; n < s_reg; n++) + { + vm_asm.push_back("push$ s" + rc_intToString(n)); + s_tmp.push_back("s" + rc_intToString(n)); + } + for(int n = 0; n < u_reg; n++) + { + vm_asm.push_back("push_t u" + rc_intToString(n)); + u_tmp.push_back("u" + rc_intToString(n)); + } + + vm_asm.push_back("gosub @" + id[expr_id].name); + } + + int ptr_count = 0; + for(int n = 0; n < id[expr_id].fn_arg.size(); n++) + { + if(id[expr_id].fn_arg_type[n] == ID_TYPE_BYREF_NUM || id[expr_id].fn_arg_type[n] == ID_TYPE_BYREF_STR || id[expr_id].fn_arg_type[n] == ID_TYPE_BYREF_USER) + ptr_count++; + } + + if(ptr_count > 0) + { + vm_asm.push_back("pop_ptr !" + rc_intToString(ptr_count)); + } + + if(id[expr_id].type == ID_TYPE_FN_NUM) + { + token_replace = "n" + rc_intToString(n_reg); + vm_asm.push_back("pop " + token_replace); + inc_n(1); + } + else if(id[expr_id].type == ID_TYPE_FN_STR) + { + token_replace = "s" + rc_intToString(s_reg); + vm_asm.push_back("pop$ " + token_replace); + inc_s(1); + } + else if(id[expr_id].type == ID_TYPE_FN_USER) + { + token_replace = "u" + rc_intToString(u_reg); + //vm_asm.push_back("dim_type " + token_replace + " " + rc_intToString(id[expr_id].type_index)); NOTE: I decided to have pop_t free the memory for the variable before setting it + vm_asm.push_back("pop_t " + token_replace); + resolveID_id_reg.push_back(token_replace); + resolveID_id_type.push_back(ID_TYPE_USER); + resolveID_id_ut_index.push_back(id[expr_id].type_index); + resolveID_id_vec_pos.push_back(expr_id); + inc_u(1); + } + else if(id[expr_id].type == ID_TYPE_SUB) + { + token_replace = "?"; + } + + //cout << "start_dbg USER DT" << endl; + + if(!id[expr_id].isBuiltin) + { + for(int n = n_tmp.size()-1; n >= 0; n--) + { + vm_asm.push_back("pop " + n_tmp[n]); + } + for(int n = s_tmp.size()-1; n >= 0; n--) + { + vm_asm.push_back("pop$ " + s_tmp[n]); + } + for(int n = u_tmp.size()-1; n >= 0; n--) + { + vm_asm.push_back("pop_t " + u_tmp[n]); + } + n_tmp.clear(); + s_tmp.clear(); + u_tmp.clear(); + } + + //cout << "end dbg" << endl; + +// if(isInFunctionScope) +// { +// for(int n = id[expr_id].fn_var.size()-1; n >= 0; n--) +// { +// if(id[expr_id].fn_var[n].type == ID_TYPE_NUM || id[expr_id].fn_var[n].type == ID_TYPE_BYREF_NUM || id[expr_id].fn_var[n].type == ID_TYPE_ARR_NUM) +// { +// vm_asm.push_back("pop " + id[expr_id].fn_var[n].vec_str); +// } +// else +// { +// vm_asm.push_back("pop$ " + id[expr_id].fn_var[n].vec_str); +// } +// } +// } + + for(int p = arr_token_start; p <= arr_token_end; p++) + token[p] = ""; + + if(token_replace.compare("")==0) + { + rc_setError("Could not resolve function " + id[expr_id].name); + return false; + } + + token[arr_token_start] = token_replace; + + //cout << "the end of function: " << i << ", " << end_token << " ---> " << token[i] << endl; + + //if token is then I am going to subtract 1 from i so that when it goes back through the loop and increments i, it will be child + i--; + + } + } + else if(token[i].compare("")==0) + { + cout << "USER DEFINED TYPE REGISTER ARGUMENT" << endl; + + n = "n" + rc_intToString(n_reg); + s = "s" + rc_intToString(s_reg); + u = "u" + rc_intToString(u_reg); + + string expr_ureg = ""; + bool should_eval = false; + string expr_member = ""; + if(i < end_token) + expr_member = token[i+1]; + + if(expr_member.find_first_of(">") != string::npos) + expr_member = expr_member.substr(expr_member.find_first_of(">")+1); + + for(int t = i-1; t >= 0; t--) + { + if(token[t].compare("")!=0) + { + if(token[t].substr(0,1).compare("u")==0) + { + expr_ureg = token[t]; + should_eval = true; + token[t] = ""; + } + //cout << "break token = " << token[t] << " :: " << should_eval << endl; + break; + } + } + + if(!should_eval) + { + continue; + } + else + { + //cout << "EVAL SUPER UDT" << endl; + //continue; + } + + //user type expression from another user type expression (ie. something already stored in u register) + //cout << "-Parsing User Variable: " << id[expr_id].name << endl; + // cout << "----------------------------------------------- : " << eval_udt << endl; + + bool udt_id_init = false; + + + vm_asm.push_back("obj_usr_init " + expr_ureg); + token[i] = ""; + int ureg_index = getResolveReg(expr_ureg); + int ureg_id = resolveID_id_vec_pos[ureg_index]; + string tmp_scope = id[ureg_id].scope + "." + id[ureg_id].name; + + /* + cout << "Resolve = " << ureg_id << ": " << tmp_scope << endl; + + for(int t = i; t < token.size(); t++) + { + try + { + cout << t << ":" << token.at(t) << endl; + } + catch(out_of_range& e) + { + cout << "Token Out of Range Error: " << e.what() << endl; + } + } + */ + + int tmp_id = 0; + bool has_child = false; + + + for(int t = i+1; t <= end_token; t++) + { + + if(token[t].substr(0,4).compare("")==0) + { + //cout << "FIGURE IT OUT: " << t << token[t] << endl; + string args[3]; + int arg_count = 0; + string full_id = token[t].substr(4); + token[t] = ""; + tmp_id = getIDInScope_ByIndex_TypeMatch(full_id, tmp_scope); + //cout << "\ntmp_id = " << tmp_id << endl; + + if(tmp_id < 0) + { + rc_setError(tmp_scope.substr(5) + " does not have member \"" + full_id + "\""); + return false; + } + + //cout << "Scope = " << id[tmp_id].scope << " ID = " << full_id << " -- " << tmp_id << endl << endl; + + tmp_scope += "." + full_id; + + + //get arguments (ie. the dimensions of an array + int t2 = t+1; + + if(t2 < end_token) + { + int arr_scope = 0; + if(token[t2].compare("!")==0) + { + token[t2] = ""; + args[0] = ""; + args[1] = ""; + args[2] = ""; + arg_count = 0; + arr_scope = 1; + t2++; + //cout << "T2 = " << t2 << endl << endl; + + for(; t2 <= end_token; t2++) + { + //cout << "DBG ARR: " << t2 << ", " << end_token << " : " << token[t2] << endl; + if(token[t2].compare("!")==0) + arr_scope--; + else if(token[t2].compare("!")==0) + arr_scope++; + else if(token[t2].compare("!")==0) + arg_count++; + else if(token[t2].substr(0,1).compare("n")==0) + { + if(args[arg_count].compare("")==0) + args[arg_count] = token[t2]; + else + { + rc_setError("Error parsing array dimension: " + args[arg_count] + " :: " + token[t2] + " -- " + rc_intToString(t2) + ", " + rc_intToString(arg_count)); + return false; + } + } + + token[t2] = ""; + + if(arg_count >= 3) + { + rc_setError("Too many dimensions in array"); + return false; + } + + if(arr_scope == 0) + break; + + } + + if(arr_scope > 0) + { + rc_setError("Expected ]] in expression: " + rc_intToString(arr_scope)); + return false; + } + + arg_count++; + } + + } + + + has_child = false; + if((t2+1) < token.size()) + { + if(token[t2+1].compare("")==0) + { + has_child = true; + } + } + + + if(arg_count != id[tmp_id].num_args) + { + if(!type_delete_flag) + { + rc_setError("[0]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name); + return false; + } + else + { + if(has_child) + { + rc_setError("[1]Expected " + rc_intToString(id[tmp_id].num_args) + " dimension in " + id[tmp_id].name); + return false; + } + + arg_count = id[tmp_id].num_args; + //vm_asm.push_back("mov n" + rc_intToString(n_reg) + " 0"); + //args[0] = "n" + rc_intToString(n_reg); + //args[1] = args[0]; + //args[2] = args[0]; + //inc_n(1); + } + } + + if(type_delete_flag && (!has_child)) + { + //DO NOTHING + //cout << "NO CHILD: " << id[tmp_id].name << endl; + } + else + { + //if(type_delete_flag) + // cout << "TESTING STUFF" << endl; + + switch(arg_count) + { + case 0: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init !" + rc_intToString(id[tmp_id].vec_pos)); + else + vm_asm.push_back("obj_usr !" + rc_intToString(id[tmp_id].vec_pos)); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n !" + rc_intToString(id[tmp_id].vec_pos)); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s !" + rc_intToString(id[tmp_id].vec_pos)); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + case 1: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + else + vm_asm.push_back("obj_usr1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s1 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0]); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + case 2: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + else + vm_asm.push_back("obj_usr2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s2 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1]); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + case 3: + if(id[tmp_id].type == ID_TYPE_USER || id[tmp_id].type == ID_TYPE_BYREF_USER) + { + if(udt_id_init) + vm_asm.push_back("obj_usr_init3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + else + vm_asm.push_back("obj_usr3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + } + else if(id[tmp_id].type == ID_TYPE_USER_NUM) + vm_asm.push_back("obj_usr_n3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + else if(id[tmp_id].type == ID_TYPE_USER_STR) + vm_asm.push_back("obj_usr_s3 !" + rc_intToString(id[tmp_id].vec_pos) + " " + args[0] + " " + args[1] + " " + args[2]); + else + { + rc_setError("Invalid type in User Defined Type"); + return false; + } + break; + } + + udt_id_init = false; + } + + + + } + else if(token[t].compare("")==0) + { + token[t] = ""; + continue; + } + else if(token[t].compare("")!=0) + { + break; + } + + } + + + //START HERE + if(type_delete_flag && (!has_child)) + { + //cout << "DELETE_VAR = " << id[tmp_id].name << endl; + type_delete_arg = "!" + rc_intToString(id[tmp_id].vec_pos); + } + else + switch(id[tmp_id].type) + { + case ID_TYPE_USER: + case ID_TYPE_BYREF_USER: + vm_asm.push_back("obj_usr_get " + u); + token[i] = u; + resolveID_id_reg.push_back(token[i]); + resolveID_id_type.push_back(id[tmp_id].type); + resolveID_id_ut_index.push_back(id[tmp_id].type_index); + resolveID_id_vec_pos.push_back(tmp_id); + inc_u(1); + break; + case ID_TYPE_USER_NUM: + vm_asm.push_back("obj_usr_get " + n); + token[i] = n; + inc_n(1); + break; + case ID_TYPE_USER_STR: + vm_asm.push_back("obj_usr_get " + s); + token[i] = s; + inc_s(1); + break; + default: + break; + } + + /* + cout << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" << endl; + + for(int t = 0; t < token.size(); t++) + { + try + { + cout << t << ":" << token.at(t) << endl; + } + catch(out_of_range& e) + { + cout << "Token Out of Range Error: " << e.what() << endl; + } + } + + cout << "-----------------------------------------------" << endl; + */ + + //for(int t = 0; t < id.size(); t++) + // if(id[t].type == ID_TYPE_USER) cout << "ID[" << id[t].name << "] SCOPE=" << id[t].scope << " -- " << id[t].vec_pos << endl; + } + } + return true; +} + +// I really hate Wal-Mart + +struct block_argument +{ + int arg_start = -1; + int arg_end = -1; +}; + +vector block_args; +vector block_arg_data; + +bool getArgBlockStuff(int start_block, int& arg_count) +{ + block_args.clear(); + int end_block = -1; + arg_count = 0; + //string block_type = token[start_block]; + //string block_end_type = ""; + block_argument b_arg; + +// if(block_type.compare("")==0) +// block_end_type = ""; +// else if(block_type.compare("")==0) +// block_end_type = ""; +// else if(block_type.compare("")==0) +// block_end_type = ""; +// else +// { +// rc_setError("Expected Start of Control Block"); +// return false; +// } + + if(token.size() > start_block) + { + //if its not a bracketed block then there is no need to check for arguments + if(token[start_block].compare("!")!=0 && token[start_block].compare("!")!=0 && token[start_block].compare("!")!=0) + { + arg_count = 0; + return true; + } + + int scope = 1; + b_arg.arg_start = start_block + 1; + for(int i = start_block+1; i < token.size(); i++) + { + if(token[i].compare("!")==0 || token[i].compare("!")==0 || token[i].compare("!")==0) + scope++; + else if(token[i].compare("!")==0 || token[i].compare("!")==0 || token[i].compare("!")==0) + scope--; + + if(scope == 0) + { + //getBlock should take care of this check already + // + //if(token[i].compare(block_end_type)!=0) + //{ + // rc_setError("Block was not ended correctly"); + // return false; + //} + //else + // end_block = i; + + arg_count++; + b_arg.arg_end = i - 1; + block_args.push_back(b_arg); + break; + } + else if(scope == 1) + { + if(token[i].compare("")==0) + { + token[i] = "!" + token[i]; + arg_count++; + + b_arg.arg_end = i-1; + block_args.push_back(b_arg); + b_arg.arg_start = i + 1; + } + } + } + } + + return true; +} + +bool getBlockArg(int arg_num, int& start_arg, int& end_arg) +{ + if(arg_num < block_args.size()) + { + start_arg = block_args[arg_num].arg_start; + end_arg = block_args[arg_num].arg_end; + } + else + { + start_arg = -1; + end_arg = -1; + return false; + } + return true; +} + +string multi_arg[64]; +int multi_arg_count = 0; + +bool eval_expression(int start_token = 0, int end_token = 0, bool allow_multi_arg = false) +{ + int start_block = start_token; //will hold the index of the token the current block starts on + int end_block = end_token; //will hold the index of the token the current block ends on + int arg_start = 0; + int arg_end = 0; + int arg_count = 0; + + multi_arg[0] = ""; + multi_arg[1] = ""; + multi_arg[2] = ""; + + expr_result = ""; + + int current_block_start = 0; + int current_block_end = 0; + + if(end_token==0) + end_token = token.size()-1; + + pre_parse(start_token, end_token); + + //cout << "EXPRESSION" << endl; + //output_tokens(); + //cout << "------------------------" << endl; + + //cout << "POST PRE_PARSE" << endl; + //for(int i = start_token; i <= end_token; i++) + //cout << "Token[" << i << "]= " << token[i] << endl; + + string arg_result = ""; + + multi_arg_count = 0; + + do + { + getBlock(start_token, end_token, start_block, end_block); //sets the current start_block and end_block + + //cout << "\nstart pp" << endl; + if(!pre_parse(start_block, end_block, PP_FLAG_ARRAY, true)) + { + return false; + } + //cout << "end pp" << endl; + + getArgBlockStuff(start_block, arg_count); + + //cout << "block arg count --> " << arg_count << endl; + + //cout << "start block = " << start_token << endl << endl; cout << "end block = " << end_token << endl; + + if(end_block < 0) //if end_block is less than 0 then an error occurred so this function will return false + { + //cout << "End block < 0" << endl; + //rc_setError("Could not evaluate expression"); + return false; + } + + /* ORDER OF OPERATIONS + 1. powers + 2. multiplication, division, modulous + 3. addition, subtraction + */ + if(arg_count > 1) + { + //cout << "arg_count = " << arg_count << endl; + for(int i = 0; i < arg_count; i++) + { + getBlockArg(i, arg_start, arg_end); + + if(!eval_not(start_block, end_block)) + return false; + if(!eval_pow(arg_start, arg_end)) + return false; + if(!eval_muldiv(arg_start, arg_end)) + return false; + if(!eval_addsub(arg_start, arg_end)) + return false; + if(!eval_bitshift(arg_start, arg_end)) + return false; + if(!eval_cmp(arg_start, arg_end)) + return false; + if(!eval_andor(arg_start, arg_end)) + return false; + arg_result = ""; + + for(int n = arg_start; n <= arg_end; n++) + { + if(token[n].size()>0) + { + if(token[n].substr(0,1).compare("n")==0 || token[n].substr(0,1).compare("s")==0 || token[n].substr(0,1).compare("u")==0 || token[n].substr(0,4).compare("") == 0) + { + if(arg_result.compare("")==0) + arg_result = token[n]; + else + { + rc_setError("Found multiple args not separated by a comma"); + return false; + } + } + } + token[n] = ""; + } + token[arg_start] = arg_result; + } + } + else + { + //cout << "start" << endl; + if(!eval_not(start_block, end_block)) + return false; + if(!eval_pow(start_block, end_block)) + return false; + if(!eval_muldiv(start_block, end_block)) + return false; + if(!eval_addsub(start_block, end_block)) + return false; + if(!eval_bitshift(start_block, end_block)) + return false; + if(!eval_cmp(start_block, end_block)) + return false; + if(!eval_andor(start_block, end_block)) + return false; + //cout << "end here" << endl; + } + + //cout << "start block end = " << start_token << endl; + + }while(!(start_block==start_token && end_block==end_token)); + + int result_count = 0; + //cout << "Get RESULTS" << endl; + + for(int i = start_token; i <= end_token; i++) + { + //cout << "TOK[" << i << "] = " << token[i] << endl; + if(token[i].length()>0) + { + if(token[i].substr(0,1).compare("n")==0 || token[i].substr(0,1).compare("s")==0 || + token[i].substr(0,1).compare("u")==0 || token[i].substr(0,1).compare("?")==0) + { + expr_result = token[i]; + multi_arg[multi_arg_count] = token[i]; + multi_arg_count++; + result_count++; + } + else if(token[i].substr(0,1).compare("!")!=0) + { + rc_setError("--Could not evaluate expression: " + token[i]); + return false; + } + } + + if(result_count > 1 && !allow_multi_arg) + { + //cout << "ST:ET = " << start_block << ", " << end_block << endl; + rc_setError("++Could not evaluate expression"); + return false; + } + } + + return true; +} + +int constant_arg[64]; +int constant_arg_count = 0; + +bool eval_constantExpression(int start_token, int end_token) +{ + //cout << "constant_start = " << token[start_token] << endl; + //cout << "constant_end = " << token[end_token] << endl; + constant_arg_count = 0; + constant_arg[0] = 0; + constant_arg[1] = 0; + constant_arg[2] = 0; + for(int i = start_token; i <= end_token; i++) + { + if(rc_substr(token[i], 0, 5).compare("")==0) + { + constant_arg[constant_arg_count] = rc_stringToInt(token[i].substr(5)); + //cout << "array dim[" << constant_arg_count << "] = " << constant_arg[constant_arg_count] << endl; + if(token.size() > (i+1)) + { + if(token[i+1].compare("")!=0 && token[i+1].compare("")!=0) + { + //cout << "Next token is " << token[i+1] << endl; + rc_setError("Expected after number constant"); + return false; + } + } + } + else if(rc_substr(token[i],0, 7).compare("")==0) + { + constant_arg_count++; + if(constant_arg_count >= 3) + { + rc_setError("Too many arguments in member definition"); + return false; + } + } + else + { + rc_setError("Expected constant in member definition"); + return false; + } + + } + constant_arg_count++; + return true; +} + +int findFirstDelimiter(string line) +{ + for(int i = 0; i < line.length(); i++) + { + if(line[i] == '.' || line[i] == '[' || line[i] == ']' || line[i] == ' ') + return i; + } + return line.length()-1; +} + +bool isDelimiter(char c) +{ + switch(c) + { + case '+': + case '-': + case '*': + case '/': + case '^': + case ',': + case '=': + case '<': + case '>': + case ' ': + return true; + break; + } + return false; +} + +void clearRegs() +{ + n_reg = 0; + s_reg = 0; + u_reg = 0; + resolveID_id_reg.clear(); + resolveID_id_type.clear(); + resolveID_id_ut_index.clear(); + resolveID_id_vec_pos.clear(); +} + +bool check_rule() +{ + if(token.size()>0) + { + if(current_block_state == BLOCK_STATE_TYPE) + { + if(token[0].compare("")!=0 && token[0].compare("")!=0) + { + rc_setError("Expected DIM in TYPE definition"); + return false; + } + } + else if(current_block_state != BLOCK_STATE_MAIN) + { + if(token[0].compare("")==0) + { + rc_setError("TYPE cannot be declared in the current scope"); + return false; + } + else if(token[0].compare("")==0) + { + rc_setError("FUNCTION cannot be declared in the current scope"); + return false; + } + else if(token[0].compare("")==0) + { + rc_setError("SUB ROUTINE cannot be declared in the current scope"); + return false; + } + } + + if(token[0].compare("")==0) + { + if(token.size() < 3) + { + rc_setError("Incomplete Constant Expression"); + return false; + } + + if(token[1].substr(0,4).compare("")!=0) + { + rc_setError("Expected Identifier after CONST"); + return false; + } + + string id_name = token[1].substr(4); + + if(!isValidIDName(id_name)) + { + rc_setError("Invalid Identifier after CONST"); + return false; + } + + if(token[2].compare("")!=0) + { + rc_setError("Expected \"=\" in CONST expression"); + return false; + } + + int c_id = create_constant(StringToUpper(id_name)); + if(c_id < 0) + { + rc_setError("CONST identifier already exists"); + return false; + } + + for(int i = 3; i < token.size(); i++) + add_const_token(c_id, token[i]); + + return true; + } + else if(token[0].compare("")==0) + { + //cout << "DIM RULE FOUND" << endl; //'DIM' [ID]; '[' #; #; # ']' ; 'AS' [TYPE]; '=' (VALUE) + + string id_name = ""; + int id_type = ID_TYPE_NUM; + string id_type_name = ""; + int dimensions = 0; + + //check if the next token is a identifier + if(token.size() > 1) + { + if(token[1].substr(0,4).compare("")==0) + { + //if the identifier is not a valid name then return false + id_name = token[1].substr(4); + id_type = ID_TYPE_NUM; + id_type_name = ""; + dimensions = 0; + + if(!isValidIDName(id_name)) + { + rc_setError("Invalid Identifier name"); + return false; + } + + //check if the data type is a string + if(id_name.substr(id_name.length()-1).compare("$")==0) + id_type = ID_TYPE_STR; + + //if the identifier already exists and current_block state is not type then return false + if(idExistsInScope(id_name)) + { + rc_setError("Identifier already defined in current scope"); + return false; + } + + //cout << "db1\n"; + + //if there are only two tokens then return here because there is nothing left to check + if(token.size()==2) + { + if(current_block_state == BLOCK_STATE_TYPE) + { + //cout << "adding type member" << endl; + if(!add_type_member(id_name, id_type, "", 0)) + { + //cout << rc_getError() << endl; + return false; + } + } + else if(isInFunctionScope) + { + if(!create_function_variable(id_name, id_type, "")) + { + //cout << rc_getError() << endl; + return false; + } + } + else + { + if(!create_variable(id_name, id_type)) + { + //cout << rc_getError() << endl; + return false; + } + } + + //cout << "return true here" << endl; + return true; + } + + //cout << "db2\n"; + + //current token + int token_index = 2; + + //check for the next rule; must be [], AS, or = + //cout << "token = " << token[token_index] << endl; + if(token[token_index].compare("")==0 && current_block_state == BLOCK_STATE_TYPE) + { + //token_index++; + int end_token = token_index+1; + int sq_scope = 1; + for(; end_token < token.size(); end_token++) + { + if(token[end_token].compare("")==0) + sq_scope++; + else if(token[end_token].compare("")==0) + sq_scope--; + + if(sq_scope==0) + break; + } + if(sq_scope != 0) + { + rc_setError("Expected ] in array definition"); + return false; + } + /*if(end_token > token_index) + end_token--; + else + { + rc_setError("Expected atleast 1 parameter in member array definition"); + return false; + }*/ + //if(eval_constantExpression(token_index, end_token)) + //cout << "EVAL EXPR" << endl; + if(eval_expression(token_index, end_token, true)) + { + dimensions = multi_arg_count; + } + else + { + rc_setError("Expected constant for type member array"); + return false; + } + + token_index = end_token+1; + + //cout << "DBG token = " << token[token_index] << std::endl; + + if(token.size() > token_index) + { + if(token[token_index].compare("")==0) + { + token_index++; + if(token[token_index].substr(0,4).compare("")!=0) + { + rc_setError("Invalid type identifier name in DIM"); + return false; + } + + id_type = ID_TYPE_USER; + id_type_name = token[token_index].substr(4); + //cout << "Add member (" << id_name << ") of type (" << id_type_name << ") with " << dimensions << " dimensions [" << constant_arg[0] << "," << constant_arg[1] << "," << constant_arg[2] << "]" << endl; + //if(!add_type_member(id_name, id_type, id_type_name, dimensions, constant_arg[0], constant_arg[1], constant_arg[2])) + if(!add_type_member(id_name, id_type, id_type_name, dimensions, multi_arg[0], multi_arg[1], multi_arg[2])) + return false; + } + else + { + rc_setError("Invalid member array declaration in DIM"); + return false; + } + } + else + { + //cout << "Add member (" << id_name << ") of type (num/str) with " << dimensions << " dimensions [" << constant_arg[0] << "," << constant_arg[1] << "," << constant_arg[2] << "]" << endl; + //if(!add_type_member(id_name, id_type, "", dimensions, constant_arg[0], constant_arg[1], constant_arg[2])) + if(!add_type_member(id_name, id_type, "", dimensions, multi_arg[0], multi_arg[1], multi_arg[2])) + return false; + } + + return true; + + } + else if(token[token_index].compare("")==0) + { + multi_arg[0] = ""; + multi_arg[1] = ""; + multi_arg[2] = ""; + multi_arg_count = 0; + int end_token = token_index+1; + int sq_scope = 1; + for(; end_token < token.size(); end_token++) + { + if(token[end_token].compare("")==0) + sq_scope--; + else if(token[end_token].compare("")==0) + sq_scope++; + + if(sq_scope==0) + break; + } + if(sq_scope != 0) + { + rc_setError("Expected ] in array definition"); + return false; + } + if(!eval_expression(token_index, end_token, true)) + { + rc_setError("Could not evaluate expression in array definition"); + return false; + } + if(multi_arg_count <= 0 || multi_arg_count > 3) + { + rc_setError("Expected 1 to 3 Arguments for array definition, Found " + rc_intToString(multi_arg_count)); + return false; + } + else + { + //cout << "M_ARG[0] = " << multi_arg[0] << endl; + //cout << "M_ARG[1] = " << multi_arg[1] << endl; + //cout << "M_ARG[2] = " << multi_arg[2] << endl; + dimensions = multi_arg_count; + } + token_index = end_token+1; + + if(token.size()>token_index) + { + if(token[token_index].compare("")==0) + { + token_index++; + if(token.size()>token_index) + { + if(token[token_index].substr(0,4).compare("")!=0) + { + rc_setError("Invalid type identifier in DIM"); + return false; + } + + id_type_name = token[token_index].substr(4); + + //cout << "DIM <" << id_name << "> AS < " << id_type_name << " ["; + switch(dimensions) + { + case 1: + //cout << multi_arg[0] << "] >" << endl; + break; + case 2: + //cout << multi_arg[0] << ", " << multi_arg[1] << "] >" << endl; + break; + case 3: + //cout << multi_arg[0] << ", " << multi_arg[1] << ", " << multi_arg[2] << "] >" << endl; + break; + default: + rc_setError("Too many arguments in DIM"); + return false; + } + + create_array(id_name, ID_TYPE_USER, id_type_name, dimensions, multi_arg[0], multi_arg[1], multi_arg[2]); + //vm_asm.push_back("preset_t !" + ) + //cout << "Create FN USER ARRAY - " << id_name << endl; + return true; + } + else + { + rc_setError("Expected type identifier in DIM"); + return false; + } + } + else + { + rc_setError("Invalid array type definition"); + return false; + } + } + } + else if(token[token_index].compare("")==0) + { + id_type = ID_TYPE_USER; + + if(token.size() != 4) + { + rc_setError("Expected single type identifier in DIM"); + return false; + } + else if(token[3].substr(0,4).compare("")!=0) + { + rc_setError("Invalid type identifier name in DIM"); + return false; + } + + if(current_block_state == BLOCK_STATE_TYPE) + { + //cout << "create member (" << id_name << ") of type " << token[3].substr(4) << endl; + if(!add_type_member(id_name, ID_TYPE_USER, token[3].substr(4), 0)) + return false; + } + else + { + cout << "create variable (" << id_name << ") of type " << token[3].substr(4) << endl; + if(!create_variable(id_name, id_type, token[3].substr(4))) + return false; + } + + return true; + } + + if(token.size()>token_index) + { + rc_setError("Invalid variable definition: " + token[token_index] + ", " + rc_intToString(current_block_state) + " <--> " + rc_intToString(BLOCK_STATE_TYPE)); + return false; + } + + } + else + { + //if the next token is not an id then the syntax is incorrect and false is returned + rc_setError("Expected Identifier name"); + return false; + } + + if(dimensions > 0) + { + switch(id_type) + { + case ID_TYPE_NUM: + id_type = ID_TYPE_ARR_NUM; + break; + case ID_TYPE_STR: + id_type = ID_TYPE_ARR_STR; + break; + } + if(isInFunctionScope) + { + if(!create_function_array(id_name,id_type, dimensions, multi_arg[0], multi_arg[1], multi_arg[2])) + { + return false; + } + } + else if(!create_array(id_name, id_type, id_type_name, dimensions, multi_arg[0], multi_arg[1], multi_arg[2])) + { + //cout << rc_getError() << endl; + return false; + } + //cout << "Created Array: " << id_name << " of type " << id_type << endl; + } + else + { + if(!create_variable(id_name, id_type, id_type_name)) + { + //cout << rc_getError() << endl; + return false; + } + } + + } + else + { + //if the size of the token vector is not greater than one then the syntax for the line is incomplete so I return false + rc_setError("Expected Identifier name"); + return false; + } + } + else if(token[0].compare("")==0) + { + //cout << "REDIM RULE FOUND" << endl; //'DIM' [ID]; '[' #; #; # ']' ; 'AS' [TYPE]; '=' (VALUE) + + string id_name = ""; + int id_type = ID_TYPE_NUM; + string id_type_name = ""; + int dimensions = 0; + int id_index = -1; + + //check if the next token is a identifier + if(token.size() > 1) + { + if(token[1].substr(0,4).compare("")==0) + { + //if the identifier is not a valid name then return false + id_name = token[1].substr(4); + id_type = ID_TYPE_NUM; + id_type_name = ""; + dimensions = 0; + + if(!isValidIDName(id_name)) + { + rc_setError("Invalid Identifier name"); + return false; + } + + + id_index = getIDInScope_ByIndex(id_name); + //cout << "debug 0: " << id_index << " -> " << id[id_index].name << " --- " << id[id_index].vec_pos << endl; + + //if the identifier already exists and current_block state is not type then return false + if(id_index < 0) + { + rc_setError("Identifier was not defined in current scope"); + return false; + } + + + if(id[id_index].num_args <= 0) + { + rc_setError("REDIM expected array identifier"); + return false; + } + + + id_type = id[id_index].type; + + //cout << "db1\n"; + + //if there are only two tokens then return here because there is nothing left to check + if(token.size()==2) + { + rc_setError("Dimensions must be specified for REDIM"); + //cout << "return true here" << endl; + return false; + } + + //cout << "db2\n"; + + //current token + int token_index = 2; + + //check for the next rule; must be [], AS, or = + if(token[token_index].compare("")==0 && current_block_state == BLOCK_STATE_TYPE) + { + token_index++; + int end_token = token_index; + int sq_scope = 1; + for(; end_token < token.size(); end_token++) + { + if(token[end_token].compare("")==0) + sq_scope++; + else if(token[end_token].compare("")==0) + sq_scope--; + + if(sq_scope==0) + break; + } + if(sq_scope != 0) + { + rc_setError("Expected ] in array definition"); + return false; + } + if(end_token > token_index) + end_token--; + else + { + rc_setError("Expected atleast 1 parameter in member array definition"); + return false; + } + if(eval_constantExpression(token_index, end_token)) + { + dimensions = constant_arg_count; + } + else + { + rc_setError("Expected constant for type member array"); + return false; + } + token_index = end_token+2; + + } + else if(token[token_index].compare("")==0) + { + multi_arg[0] = ""; + multi_arg[1] = ""; + multi_arg[2] = ""; + multi_arg_count = 0; + int end_token = token_index+1; + int sq_scope = 1; + for(; end_token < token.size(); end_token++) + { + if(token[end_token].compare("")==0) + sq_scope--; + else if(token[end_token].compare("")==0) + sq_scope++; + + if(sq_scope==0) + break; + } + + if(sq_scope != 0) + { + rc_setError("Expected ] in array definition"); + return false; + } + + //cout << "debug 1: " << id_index << endl; + + if(!eval_expression(token_index, end_token, true)) + { + rc_setError("Could not evaluate expression in array definition"); + return false; + } + + //cout << "debug 2: " << id_index << endl; + + if(multi_arg_count <= 0 || multi_arg_count > 3) + { + rc_setError("Expected 1 to 3 Arguments for array re-dimension, Found " + rc_intToString(multi_arg_count)); + return false; + } + else + { + //cout << "M_ARG[0] = " << multi_arg[0] << endl; + //cout << "M_ARG[1] = " << multi_arg[1] << endl; + //cout << "M_ARG[2] = " << multi_arg[2] << endl; + dimensions = multi_arg_count; + } + token_index = end_token+1; + + //cout << "debug 3: " << id_index << endl; + } + else + { + rc_setError("Expected dimensions for REDIM"); + return false; + } + + if(token.size()>token_index) + { + rc_setError("Invalid use of REDIM"); + return false; + } + + //cout << "debug 4: " << id_index << endl; + + } + else + { + //if the next token is not an id then the syntax is incorrect and false is returned + rc_setError("Expected Identifier name"); + return false; + } + + if(dimensions > 0) + { + //cout << "debug 5: " << id_index << endl; + switch(id_type) + { + case ID_TYPE_NUM: + id_type = ID_TYPE_ARR_NUM; + break; + case ID_TYPE_STR: + id_type = ID_TYPE_ARR_STR; + break; + } + + //cout << "debug 6: " << id_index << endl; + + if(id[id_index].num_args != dimensions) + { + id[id_index].num_args = dimensions; + } + + //cout << "debug 7: " << id_index << " -- " << id[id_index].type << endl; + + if(id[id_index].type == ID_TYPE_NUM || id[id_index].type == ID_TYPE_ARR_NUM) + { + //cout << "debug 8" << endl; + switch(dimensions) + { + case 1: + vm_asm.push_back("redim1 !" + rc_intToString(id[id_index].vec_pos) + " " + multi_arg[0]); + break; + case 2: + vm_asm.push_back("redim2 !" + rc_intToString(id[id_index].vec_pos) + " " + multi_arg[0] + " " + multi_arg[1]); + break; + case 3: + vm_asm.push_back("redim3 !" + rc_intToString(id[id_index].vec_pos) + " " + multi_arg[0] + " " + multi_arg[1] + " " + multi_arg[2]); + break; + default: + rc_setError("Invalid number of dimensions in REDIM"); + return false; + } + } + else if(id[id_index].type == ID_TYPE_STR || id[id_index].type == ID_TYPE_ARR_STR) + { + switch(dimensions) + { + case 1: + vm_asm.push_back("redim1$ !" + rc_intToString(id[id_index].vec_pos) + " " + multi_arg[0]); + break; + case 2: + vm_asm.push_back("redim2$ !" + rc_intToString(id[id_index].vec_pos) + " " + multi_arg[0] + " " + multi_arg[1]); + break; + case 3: + vm_asm.push_back("redim3$ !" + rc_intToString(id[id_index].vec_pos) + " " + multi_arg[0] + " " + multi_arg[1] + " " + multi_arg[2]); + break; + default: + rc_setError("Invalid number of dimensions in REDIM"); + return false; + } + } + else + { + rc_setError("Invalid type for REDIM"); + return false; + } + //cout << "balls" << endl; + return true; + } + else + { + rc_setError("Expected dimensions in REDIM"); + return false; + } + + } + else + { + //if the size of the token vector is not greater than one then the syntax for the line is incomplete so I return false + rc_setError("Expected Identifier name"); + return false; + } + //cout << "debug final" << endl; + } + else if(token[0].compare("")==0) + { + if(token.size()==1) + { + vm_asm.push_back("end"); + return true; + } + if(token[1].compare("")==0) + { + if(token.size()>2) + { + rc_setError("Expected End of Line in END FUNCTION"); + return false; + } + if(current_block_state != BLOCK_STATE_FUNCTION) + { + rc_setError("Cannot exit function from this scope"); + return false; + } + + //int ptr_count = 0; + //for(int n = 0; n < id[current_fn_index].fn_arg.size(); n++) + //{ + // if(id[current_fn_index].fn_arg_type[n] == ID_TYPE_BYREF_NUM || id[current_fn_index].fn_arg_type[n] == ID_TYPE_BYREF_STR) + // { + // ptr_count++; + // } + //} + + //if(ptr_count > 0) + // vm_asm.push_back("pop_ptr !" + rc_intToString(ptr_count)); + if(id[current_fn_index].type == ID_TYPE_FN_NUM) + { + vm_asm.push_back("push 0"); + vm_asm.push_back("return"); + vm_asm.push_back(".code"); + vm_asm.n_stack_count = 0; + } + else if(id[current_fn_index].type == ID_TYPE_FN_STR) + { + vm_asm.push_back("push_empty$"); + vm_asm.push_back("return"); + vm_asm.push_back(".code"); + vm_asm.s_stack_count = 0; + } + else if(id[current_fn_index].type == ID_TYPE_FN_USER) + { + vm_asm.push_back("dim_type u0 !" + rc_intToString(id[current_fn_index].type_index)); + vm_asm.push_back("push_t u0"); + vm_asm.push_back("return"); + vm_asm.push_back(".code"); + vm_asm.u_stack_count = 0; + } + block_state.pop(); + current_block_state = BLOCK_STATE_MAIN; + isInFunctionScope = false; + current_scope = "main"; + + for(uint64_t i = 0; i < id[current_fn_index].fn_arg.size(); i++) + { + uint64_t id_vec = id[current_fn_index].fn_arg_vec[i]; + uint64_t id_type = id[current_fn_index].fn_arg_type[i]; + uint64_t id_utype = id[current_fn_index].fn_arg_utype[i]; + + if(id_type == ID_TYPE_USER) + { + vm_asm.push_back("dim_type !" + rc_intToString(id_vec) + " !" + rc_intToString(id_utype)); + } + } + + current_fn_index++; + } + else if(token[1].compare("")==0) + { + if(token.size()>2) + { + rc_setError("Expected End of Line in END SUB"); + return false; + } + if(current_block_state != BLOCK_STATE_SUB) + { + rc_setError("Cannot exit sub routine from this scope"); + return false; + } + + //int ptr_count = 0; + //for(int n = 0; n < id[current_fn_index].fn_arg.size(); n++) + //{ + // if(id[current_fn_index].fn_arg_type[n] == ID_TYPE_BYREF_NUM || id[current_fn_index].fn_arg_type[n] == ID_TYPE_BYREF_STR) + // { + // ptr_count++; + // } + //} + + //if(ptr_count > 0) + // vm_asm.push_back("pop_ptr !" + rc_intToString(ptr_count)); + + vm_asm.push_back("return"); + vm_asm.push_back(".code"); + + block_state.pop(); + current_block_state = BLOCK_STATE_MAIN; + isInFunctionScope = false; + current_scope = "main"; + + for(uint64_t i = 0; i < id[current_fn_index].fn_arg.size(); i++) + { + uint64_t id_vec = id[current_fn_index].fn_arg_vec[i]; + uint64_t id_type = id[current_fn_index].fn_arg_type[i]; + uint64_t id_utype = id[current_fn_index].fn_arg_utype[i]; + + if(id_type == ID_TYPE_USER) + { + vm_asm.push_back("dim_type !" + rc_intToString(id_vec) + " !" + rc_intToString(id_utype)); + } + } + + current_fn_index++; + } + else if(token[1].compare("")==0) + { + if(token.size()>2) + { + rc_setError("Expected End of Line in END TYPE"); + return false; + } + if(current_block_state != BLOCK_STATE_TYPE) + { + rc_setError("Cannot exit TYPE definition from this scope"); + return false; + } + + block_state.pop(); + current_block_state = BLOCK_STATE_MAIN; + current_scope = "main"; + } + else if(token[1].compare("")==0) + { + if(token.size() > 2) + { + rc_setError("Expected End of Line in END IF"); + return false; + } + if(current_block_state != BLOCK_STATE_IF) + { + rc_setError("Cannot END IF without starting an IF Block"); + return false; + } + block_state.pop(); + current_block_state = block_state.top(); + + vm_asm.push_back("label ELSE:" + rc_intToString(if_block.top().index) + "->CONDITION:" + rc_intToString(if_block.top().condition)); + vm_asm.push_back("label ENDIF:" + rc_intToString(if_block.top().index)); + if_block.pop(); + exit_scope(1); + } + else if(token[1].compare("")==0) + { + if(token.size() < 3) + { + rc_setError("Incomplete SELECT CASE statement"); + return false; + } + if(token[1].compare("")!=0) + { + rc_setError("Expected CASE in SELECT CASE statement"); + return false; + } + if(!eval_expression(2, token.size()-1)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + select_data select_start; + select_start.index = current_select_index; + select_start.case_index = 0; + select_start.default_set = false; + if(expr_result.substr(0,1).compare("s")==0) + { + select_start.case_type = ID_TYPE_STR; + vm_asm.push_back("push$ " + expr_result); + } + else + { + select_start.case_type = ID_TYPE_NUM; + vm_asm.push_back("push " + expr_result); + } + + select_block.push(select_start); + string select_label = "SELECT:" + rc_intToString(select_block.top().index) + "->CASE:" + rc_intToString(select_block.top().case_index); + + vm_asm.push_back("jmp @" + select_label); + + current_select_index++; + current_scope += ".#" + select_label; + current_block_state = BLOCK_STATE_SELECT; + block_state.push(current_block_state); + + //vm_asm.push_back(""); + + } + else if(token[0].compare("")==0) + { + if(token.size()==1) + { + rc_setError("Expected expression in CASE"); + return false; + } + if(current_block_state != BLOCK_STATE_SELECT) + { + rc_setError("Cannot set CASE outside of a SELECT BLOCK"); + return false; + } + + + select_block.top().case_set = true; + + string compare_case = ""; + + string case_end = "SELECT:" + rc_intToString(select_block.top().index) + "->END"; + string case_label = "SELECT:" + rc_intToString(select_block.top().index) + "->CASE:" + rc_intToString(select_block.top().case_index); + exit_scope(1); + current_scope += ".#" + case_label; + + select_block.top().case_index++; + string next_case_label = "SELECT:" + rc_intToString(select_block.top().index) + "->CASE:" + rc_intToString(select_block.top().case_index); + + vm_asm.push_back("jmp @" + case_end); + vm_asm.push_back("label " + case_label); + + if(select_block.top().case_type==ID_TYPE_STR) + { + compare_case = "s" + rc_intToString(s_reg); + vm_asm.push_back("pop$ " + compare_case); + vm_asm.push_back("push$ " + compare_case); + inc_s(1); + } + else + { + compare_case = "n" + rc_intToString(n_reg); + vm_asm.push_back("pop " + compare_case); + vm_asm.push_back("push " + compare_case); + inc_n(1); + } + for(int i = 0; i < token.size(); i++) + { + if(token[i].compare("")==0) + token[i] = "!"; + } + if(!eval_expression(1, token.size()-1, true)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + string case_reg_type = "n"; + if(select_block.top().case_type == ID_TYPE_STR) + case_reg_type = "s"; + + string cmp_or_result = "n" + rc_intToString(n_reg); + inc_n(1); + + string case_flag_result = "n" + rc_intToString(n_reg); + inc_n(1); + + vm_asm.push_back("mov " + cmp_or_result + " 0"); + + for(int i = 0; i < multi_arg_count; i++) + { + if(multi_arg[i].substr(0,1).compare(case_reg_type)!=0) + { + rc_setError("Mismatch type in CASE: " + multi_arg[i]); + return false; + } + if(case_reg_type.compare("s")==0) + { + vm_asm.push_back("cmp$ " + compare_case + " " + multi_arg[i]); + vm_asm.push_back("mov " + case_flag_result + " %EQUAL_FLAG"); + vm_asm.push_back("or " + cmp_or_result + " " + case_flag_result); + } + else + { + vm_asm.push_back("cmp " + compare_case + " " + multi_arg[i]); + vm_asm.push_back("mov " + case_flag_result + " %EQUAL_FLAG"); + vm_asm.push_back("or " + cmp_or_result + " " + case_flag_result); + } + } + vm_asm.push_back("cmp " + cmp_or_result + " 0"); + vm_asm.push_back("je @" + next_case_label); + //vm_asm.push_back(""); + } + else if(token[0].compare("")==0) + { + if(token.size()>1) + { + rc_setError("Expected End of Line for default"); + return false; + } + if(current_block_state != BLOCK_STATE_SELECT) + { + rc_setError("Cannot set DEFAULT outside of a SELECT BLOCK"); + return false; + } + + + select_block.top().case_set = true; + + string compare_case = ""; + + string case_end = "SELECT:" + rc_intToString(select_block.top().index) + "->END"; + string case_label = "SELECT:" + rc_intToString(select_block.top().index) + "->CASE:" + rc_intToString(select_block.top().case_index); + exit_scope(1); + current_scope += ".#" + case_label; + + select_block.top().case_index++; + string next_case_label = "SELECT:" + rc_intToString(select_block.top().index) + "->CASE:" + rc_intToString(select_block.top().case_index); + + vm_asm.push_back("jmp @" + case_end); + vm_asm.push_back("label " + case_label); + + //vm_asm.push_back(""); + } + else if(token[0].compare("")==0) + { + string last_token = token[token.size()-1]; + if(token.size()==1) + { + rc_setError("Expected expression for PRINT"); + return false; + } + int start_token = 1; + if(token[token.size()-1].compare("")!=0) + token.push_back(""); + for(int i = 0; i < token.size(); i++) + { + if(token[i].compare("")==0) + { + token[i] = ""; + if(!eval_expression(start_token, i)) + { + //rc_setError("Could not evaluate expression"); + //output_tokens(); + cout << endl << endl; + return false; + } + if(expr_result.substr(0,1).compare("n")==0) + vm_asm.push_back("print " + expr_result); + else + vm_asm.push_back("print$ " + expr_result); + start_token = i; + } + } + if(start_token < (token.size()-1 ) ) + { + if(!eval_expression(start_token, token.size()-1)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + if(expr_result.substr(0,1).compare("n")==0) + vm_asm.push_back("print " + expr_result); + else + vm_asm.push_back("print$ " + expr_result); + } + if(last_token.compare("")!=0) + vm_asm.push_back("println"); + } + else if(token[0].compare("")==0) + { + if(token.size() < 2) + { + rc_setError("Expected single identifier in DELETE statement"); + return false; + } + if(token[1].substr(0,4).compare("")!=0) + { + rc_setError("Expected single identifier in DELETE statement"); + return false; + } + int id_index = getIDInScope_ByIndex(token[1].substr(4)); + if(id_index < 0) + { + rc_setError("Identifier does not exists in current scope: " + token[1].substr(4) + ", SCOPE=" + current_scope); + return false; + } + if(id[id_index].type == ID_TYPE_ARR_NUM || id[id_index].type == ID_TYPE_NUM) + { + if(token.size() != 2) + { + rc_setError("Expected single identifier in DELETE statement"); + return false; + } + + vm_asm.push_back("delete !" + rc_intToString(id[id_index].vec_pos)); + } + else if(id[id_index].type == ID_TYPE_ARR_STR || id[id_index].type == ID_TYPE_STR) + { + if(token.size() != 2) + { + rc_setError("Expected single identifier in DELETE statement"); + return false; + } + + vm_asm.push_back("delete$ !" + rc_intToString(id[id_index].vec_pos)); + } + else if(id[id_index].type == ID_TYPE_USER) + { + token[0] = ""; + + type_delete_flag = true; + type_delete_arg = ""; + + if(!eval_expression()) + { + rc_setError("Could not evaluate identifer"); + return false; + } + if(type_delete_arg.substr(0,1).compare("!")!=0) + { + rc_setError("Could not determine Identifier Type in DELETE: " + type_delete_arg); + return false; + } + vm_asm.push_back("delete_t " + type_delete_arg); + + type_delete_flag = false; + } + else + { + rc_setError("Cannot delete identifier of this type"); + return false; + } + //id[id_index].name = ""; + } + else if(token[0].compare("")==0) + { + if(current_scope.compare("main")!=0) + { + rc_setError("TYPE cannot be defined in this scope"); + return false; + } + if(token.size() != 2) + { + rc_setError("Expected TYPE Identifier in TYPE statement"); + return false; + } + if(token[1].substr(0,4).compare("")!=0) + { + rc_setError("Expected TYPE Identifier in TYPE statement"); + return false; + } + int id_index = getIDInScope_ByIndex(token[1].substr(4)); + if(id_index >= 0) + { + rc_setError("TYPE Identifier exists in current scope"); + return false; + } + create_type(token[1].substr(4)); + current_block_state = BLOCK_STATE_TYPE; + block_state.push(current_block_state); + + string start_label = current_scope + ".#TYPE:" + token[1].substr(4); + + current_scope = start_label; + } + else if(token.size() > 2) + { + //cout << "token[1] = " << token[1] << endl; + if(token[0].substr(0,4).compare("")==0) + { + int id_index = getIDInScope_ByIndex(token[0].substr(4)); + if(id_index >= 0) + { + //cout << "DBG TYPE: name = " << id[id_index].name << " -- type = " << id[id_index].type << " -- scope = " << id[id_index].scope << endl; + + if( ID_TYPE_USER_ALL(id_index) ) + { + //NOTE: PARSING TYPE VAR HERE + + string full_id = ""; + int tmp_scope = 0; + int end_token = -1; + int op_token = -1; + + //getting the id to parse + for(int i = 0; i < token.size(); i++) + { + //cout << "DEBUG TOKEN[" << i << "] = " << token[i] << endl; + + if(token[i].compare("")==0 || token[i].compare("!")==0 || + token[i].compare("")==0 || token[i].compare("!")==0) + tmp_scope++; + else if(token[i].compare("")==0 || token[i].compare("!")==0 || + token[i].compare("")==0 || token[i].compare("!")==0) + tmp_scope--; + else if(tmp_scope == 0 && isOperatorToken2(i)) + { + //cout << "PARSE ID = \n" << full_id << endl; + op_token = i; + end_token = i-1; + break; + } + + } + + if(end_token < 0) + { + end_token = 0; + } + + string op = ""; + + if(op_token >= 0) + { + op = token[op_token]; + token[op_token] = ""; + + if(end_token==0) + end_token++; + } + + if(!eval_expression(0, end_token)) + { + rc_setError("[1] Could not evaluate Identifier: " + rc_intToString(end_token)); + return false; + } + + if(op_token >= 0) + token[op_token] = op; + + bool set_val = false; + string id_arg = ""; + + if(op_token >= 0) + if(token[op_token].compare("")==0) + { + //cout << "BALLS" << endl; + set_val = true; + id_arg = token[0]; + for(int i = 0; i <= op_token; i++) + token[i] = ""; + + //for(int i = op_token+1; i < token.size(); i++) + // cout << "SUPER T[" << i << "] = " << token[i] << endl; + } + + if(!eval_expression()) + { + rc_setError("Could not evaluate expression"); + return false; + } + + //cout << endl << "NEW SET" << endl; + //cout << "-----------------------" << endl; + //for(int i = 0; i < token.size(); i++) + // cout << i << ":" << token[i] << endl; + //cout << endl; + + + + //I will do something with this eventually + int var_type = -1; + //cout << "Set Val = " << set_val << endl; + if(set_val) + { + if(expr_result.substr(0,1).compare(id_arg.substr(0,1))!=0) + { + rc_setError("[0]Expression type does not match identifier"); + return false; + } + + int ut_info = 0; + int ut1 = -1; + int ut2 = -1; + + var_type = id_arg.substr(0,1).compare("n")==0 ? ID_TYPE_NUM : -1; + var_type = (var_type < 0) ? (id_arg.substr(0,1).compare("s")==0 ? ID_TYPE_STR : -1) : var_type; + var_type = (var_type < 0) ? (id_arg.substr(0,1).compare("u")==0 ? ID_TYPE_USER : -1) : var_type; + switch(var_type) + { + case ID_TYPE_NUM: + vm_asm.push_back("mov_r " + id_arg + " " + expr_result); + break; + case ID_TYPE_STR: + vm_asm.push_back("mov_r$ " + id_arg + " " + expr_result); + break; + case ID_TYPE_USER: + getRegInfo(id_arg, ut_info, ut1); + getRegInfo(expr_result, ut_info, ut2); + if(ut1 != ut2) + { + rc_setError("[1]Expression type does not match identifier in assignment"); + return false; + } + vm_asm.push_back("mov_type " + id_arg + " " + expr_result); + break; + default: + //cout << "VAR_TYPE = " << var_type << endl; + break; + } + + return true; + } + } + } + } + + if(token[1].compare("")==0) + { + string var_id = ""; + int var_type = ID_TYPE_NUM; + int var_ut_index = -1; + int var_id_index = -1; + + if(rc_substr(token[0], 0, 1).compare("n")==0 || rc_substr(token[0], 0, 1).compare("s")==0) + { + for(int i = 0; i < resolveID_id_reg.size(); i++) + { + if(resolveID_id_reg[i].compare(token[0])==0) + { + var_id = "~" + token[0]; + if(token[0].substr(0,1).compare("s")==0) + var_type = ID_TYPE_STR; + else if(resolveID_id_type[i] == ID_TYPE_USER) + { + var_type = ID_TYPE_USER; + var_ut_index = resolveID_id_ut_index[i]; + } + else + var_type = resolveID_id_type[i]; + break; + } + } + if(var_id.compare("")==0) + { + rc_setError("Expected identifier for variable assignment"); + return false; + } + } + else if(rc_substr(token[0], 0, 4).compare("")==0) + { + var_id = token[0].substr(4); + var_type = (var_id.substr(var_id.length()-1).compare("$")==0) ? ID_TYPE_STR : ID_TYPE_NUM; //length() will always be atleast 1 so there is no need to check + +// if(var_id.substr(var_id.length()-1,1).compare("$")==0) +// { +// //cout << "looking for: " << var_id.substr(0, var_id.length()-1) << endl; +// var_id_index = getIDInScope(var_id.substr(0, var_id.length()-1)); +// if(var_id_index >= 0) +// var_type = id[var_id_index].type; +// //cout << "var_index = " << var_id_index << endl; +// } + if(var_id_index < 0) + { + var_id_index = getIDInScope_ByIndex(var_id); + if(var_id_index >= 0) + var_type = id[var_id_index].type; + } + + if(var_id_index < 0) + { + if(!isValidIDName(var_id)) + { + rc_setError(var_id + " is not a valid identifier"); + return false; + } + if(isInFunctionScope) + { + if(!create_function_variable(var_id, var_type, "")) + { + rc_setError("Could not create " + var_id); + return false; + } + } + else if(!create_variable(var_id, var_type)) + { + rc_setError("Could not create " + var_id); + return false; + } + + var_id_index = getIDInScope_ByIndex(var_id); + + if(var_id_index < 0) + { + rc_setError("Unexpected error"); + return false; + } + } + } + + if(var_type == ID_TYPE_BYREF_NUM) + var_type = ID_TYPE_NUM; + else if(var_type == ID_TYPE_BYREF_STR) + var_type = ID_TYPE_STR; + + if(var_type != ID_TYPE_NUM && var_type != ID_TYPE_STR) + { + bool id_type_match = false; + if(token.size()!=3) + { + rc_setError("Expected identifier of same type in assignment"); + return false; + } + + for(int i = 0; i < resolveID_id_reg.size(); i++) + { + if(resolveID_id_reg[i].compare(token[2])==0) + { + if(resolveID_id_type[i] == var_type) + { + if(var_type == ID_TYPE_USER && var_ut_index == resolveID_id_ut_index[i]) + { + id_type_match = true; + } + else if(var_type == ID_TYPE_ARR_NUM || var_type == ID_TYPE_ARR_STR) + { + id_type_match = true; + } + } + } + } + + if(!id_type_match) + { + rc_setError("Expected identifier of same type in assignment"); + return false; + } + + vm_asm.push_back("mov_type " + var_id.substr(1) + " " + token[2]); + + return true; + } + + if(!eval_expression(2)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + + if(var_type == ID_TYPE_NUM && expr_result.substr(0,1).compare("n")!=0 ) + { + rc_setError("Must set number variable to number expression"); + return false; + } + else if(var_type == ID_TYPE_STR && expr_result.substr(0,1).compare("s")!=0 ) + { + rc_setError("Must set string variable to string expression"); + return false; + } + + if(var_id.substr(0,1).compare("~")==0) + { + switch(var_type) + { + case ID_TYPE_NUM: + vm_asm.push_back("mov_r " + var_id.substr(1) + " " + expr_result); + break; + case ID_TYPE_STR: + vm_asm.push_back("mov_r$ " + var_id.substr(1) + " " +expr_result); + break; + default: + //cout << "VAR_TYPE = " << var_type << endl; + break; + } + } + else + { + switch(var_type) + { + case ID_TYPE_NUM: + vm_asm.push_back("mov !" + rc_intToString(id[var_id_index].vec_pos) + " " + expr_result); + break; + case ID_TYPE_STR: + vm_asm.push_back("mov$ !" + rc_intToString(id[var_id_index].vec_pos) + " " + expr_result); + break; + } + } + + } + else if(rc_substr(token[0], 0, 4).compare("")==0 && token.size() > 5) + { + //cout << "dbg 1" << endl; + int expr_id = getIDInScope_ByIndex(token[0].substr(4)); + + if(expr_id < 0) + { + rc_setError("Identifier \"" + token[0].substr(4) + "\" was not declared in this scope"); + return false; + } + + int start_token = 0; + int end_token = 0; + + int s_scope = 1; + + if(token[1].compare("")==0) + { + for(int i = 2; i < token.size(); i++) + { + if(token[i].compare("")==0) + s_scope--; + else if(token[i].compare("")==0) + s_scope++; + if(s_scope == 0) + { + end_token = i; + + //for(int i2 = start_token; i2 <= end_token; i2++) + // cout << "token: " << i2 << token[i2] << endl; + + break; + } + } + if(s_scope != 0) + { + rc_setError("Expected ] in array assignment"); + return false; + } + } + else + { + //cout << "dbg 2" << endl; + if(!eval_expression()) + { + rc_setError("Could not evaluate expression"); + return false; + } + } + + if(!eval_expression(start_token, end_token)) + { + rc_setError("Could not resolve array identifier"); + return false; + } + + string var = expr_result; + end_token++; + bool isAssignment = false; + + if(token.size()>end_token) + { + if(token[end_token].compare("")==0) + { + isAssignment = true; + start_token = end_token+1; + } + } + + + string var_result = ""; + if(isAssignment) + { + if(!eval_expression(start_token, token.size()-1)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + + if(var.substr(0,1).compare("n")==0 && expr_result.substr(0,1).compare("n")==0) + { + vm_asm.push_back("mov_r " + var + " " + expr_result); + return true; + } + else if(var.substr(0,1).compare("s")==0 && expr_result.substr(0,1).compare("s")==0) + { + vm_asm.push_back("mov_r$ " + var + " " + expr_result); + return true; + } + else + { + rc_setError("Identifier type does not match assignment type"); + return false; + } + + } + else + { + if(!eval_expression(start_token, token.size()-1)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + } + + } + else + { + //cout << "debug problem here" << endl; + //output_tokens(); + if(!eval_expression()) + { + //rc_setError("Could not evaluate expression"); + return false; + } + } + } + else + { + if(!eval_expression(0, token.size()-1)) + { + //rc_setError("Could not evaluate expression"); + return false; + } + //cout <<"THIS IS A TEST" << endl; + } + } + return true; +} + +bool check_rule_embedded() +{ + if(token.size() > 0) + { + if(token[0].compare("")==0) + { + if(token.size()<2) + { + rc_setError("Expected identifier for function declaration"); + return false; + } + + string fn_name = rc_substr(token[1], 4, token[1].length()); + if(!isValidIDName(fn_name) ) + { + rc_setError(fn_name + " is not a valid identifier name"); + return false; + } + if(idExistsInScope(fn_name)) + { + rc_setError("Identifier " + fn_name + " already exists in this scope"); + return false; + } + + int fn_type = ID_TYPE_FN_NUM; + if(fn_name.substr(fn_name.length()-1,1).compare("$")==0) + fn_type = ID_TYPE_FN_STR; + + embed_function(fn_name, fn_type); + current_block_state = BLOCK_STATE_FUNCTION; + block_state.push(current_block_state); + + string fn_arg = ""; + int fn_arg_type = ID_TYPE_NUM; + bool fn_byref = false; + + int end_token = 0; + + for(int i = 3; i < token.size(); i++) + { + if(token[i].compare("")==0) + { + fn_byref = true; + } + else if(rc_substr(token[i], 0, 4).compare("")==0) + { + fn_arg += token[i]; + if(fn_arg.substr(fn_arg.length()-1,1).compare("$")==0) + fn_arg_type = ID_TYPE_STR; + else + fn_arg_type = ID_TYPE_NUM; + } + else if(token[i].compare("")==0) + { + fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1); + if(!isValidIDName(fn_arg)) + { + rc_setError("Function argument is not a valid identifier name"); + return false; + } + if(idExistsInScope(fn_arg)) + { + rc_setError("Function argument identifier already exists in current scope"); + return false; + } + + if(fn_byref) + { + if(fn_arg_type == ID_TYPE_NUM) + fn_arg_type = ID_TYPE_BYREF_NUM; + else + fn_arg_type = ID_TYPE_BYREF_STR; + } + + add_embedded_arg(fn_arg, fn_arg_type); + fn_arg = ""; + fn_byref = false; + } + else if(token[i].compare("")==0) + { + if(fn_arg.compare("")==0) + { + end_token = i+1; + break; + } + fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1); + if(!isValidIDName(fn_arg)) + { + rc_setError("Function argument is not a valid identifier name"); + return false; + } + if(idExistsInScope(fn_arg)) + { + rc_setError("Function argument identifier already exists in current scope: " + fn_arg + " -> " + current_scope + " ? "); + return false; + } + + if(fn_byref) + { + if(fn_arg_type == ID_TYPE_NUM) + fn_arg_type = ID_TYPE_BYREF_NUM; + else + fn_arg_type = ID_TYPE_BYREF_STR; + } + + add_embedded_arg(fn_arg, fn_arg_type); + fn_arg = ""; + fn_byref = false; + end_token = i+1; + break; + } + else + { + rc_setError("Argument to function must be a valid identifier: " + token[i]); + return false; + } + } + + current_block_state = BLOCK_STATE_MAIN; + current_scope = "main"; + block_state.pop(); + isInFunctionScope = false; + current_fn_index++; + + if(token.size()>end_token) + { + rc_setError("Expected end of function declaration"); + return false; + } + + } + else if(token[0].compare("")==0) + { + if(token.size()<2) + { + rc_setError("Expected identifier for function declaration"); + return false; + } + + string fn_name = rc_substr(token[1], 4, token[1].length()); + if(!isValidIDName(fn_name) ) + { + rc_setError(fn_name + " is not a valid identifier name"); + return false; + } + if(idExistsInScope(fn_name)) + { + rc_setError("Identifier " + fn_name + " already exists in this scope"); + return false; + } + + int fn_type = ID_TYPE_SUB; + + embed_function(fn_name, fn_type); + current_block_state = BLOCK_STATE_SUB; + block_state.push(current_block_state); + + string fn_arg = ""; + int fn_arg_type = ID_TYPE_NUM; + bool fn_byref = false; + + int end_token = 0; + + for(int i = 3; i < token.size(); i++) + { + if(token[i].compare("")==0) + { + fn_byref = true; + } + else if(rc_substr(token[i], 0, 4).compare("")==0) + { + fn_arg += token[i]; + if(fn_arg.substr(fn_arg.length()-1,1).compare("$")==0) + fn_arg_type = ID_TYPE_STR; + else + fn_arg_type = ID_TYPE_NUM; + } + else if(token[i].compare("")==0) + { + fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1); + if(!isValidIDName(fn_arg)) + { + rc_setError("Function argument is not a valid identifier name"); + return false; + } + if(idExistsInScope(fn_arg)) + { + rc_setError("Function argument identifier already exists in current scope"); + return false; + } + + if(fn_byref) + { + if(fn_arg_type == ID_TYPE_NUM) + fn_arg_type = ID_TYPE_BYREF_NUM; + else + fn_arg_type = ID_TYPE_BYREF_STR; + } + + add_embedded_arg(fn_arg, fn_arg_type); + fn_arg = ""; + fn_byref = false; + } + else if(token[i].compare("")==0) + { + if(fn_arg.compare("")==0) + { + end_token = i+1; + break; + } + fn_arg = rc_substr(fn_arg, 4, fn_arg.length()-1); + if(!isValidIDName(fn_arg)) + { + rc_setError("Function argument is not a valid identifier name"); + return false; + } + if(idExistsInScope(fn_arg)) + { + rc_setError("Function argument identifier already exists in current scope"); + return false; + } + + if(fn_byref) + { + if(fn_arg_type == ID_TYPE_NUM) + fn_arg_type = ID_TYPE_BYREF_NUM; + else + fn_arg_type = ID_TYPE_BYREF_STR; + } + + add_embedded_arg(fn_arg, fn_arg_type); + fn_arg = ""; + fn_byref = false; + end_token = i+1; + break; + } + else + { + rc_setError("Argument to function must be a valid identifier: " + token[i]); + return false; + } + } + + current_block_state = BLOCK_STATE_MAIN; + current_scope = "main"; + block_state.pop(); + isInFunctionScope = false; + current_fn_index++; + + if(token.size()>end_token) + { + rc_setError("Expected end of function declaration"); + return false; + } + + } + } + return true; +} + +#endif // PARSER_H_INCLUDED diff --git a/rcbasic_build/rc_builtin.h b/rcbasic_build/rc_builtin.h new file mode 100644 index 0000000..f7dc2ef --- /dev/null +++ b/rcbasic_build/rc_builtin.h @@ -0,0 +1,1428 @@ +#ifndef RC_BUILTIN_H_INCLUDED +#define RC_BUILTIN_H_INCLUDED +#include "identifier.h" + +void init_embedded() +{ +embed_function("FPrint", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("Input$", ID_TYPE_FN_STR); +add_embedded_arg("prompt$", ID_TYPE_STR); +embed_function("ArrayDim", ID_TYPE_FN_NUM); +add_embedded_arg("id", ID_TYPE_BYREF_NUM); +embed_function("StringArrayDim", ID_TYPE_FN_NUM); +add_embedded_arg("id$", ID_TYPE_BYREF_STR); +embed_function("NumberArrayDim", ID_TYPE_FN_NUM); +add_embedded_arg("id", ID_TYPE_BYREF_NUM); +embed_function("ArraySize", ID_TYPE_FN_NUM); +add_embedded_arg("id", ID_TYPE_BYREF_NUM); +add_embedded_arg("array_dim", ID_TYPE_NUM); +embed_function("StringArraySize", ID_TYPE_FN_NUM); +add_embedded_arg("id$", ID_TYPE_BYREF_STR); +add_embedded_arg("array_dim", ID_TYPE_NUM); +embed_function("NumberArraySize", ID_TYPE_FN_NUM); +add_embedded_arg("id", ID_TYPE_BYREF_NUM); +add_embedded_arg("array_dim", ID_TYPE_NUM); +embed_function("Abs", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("ACos", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("AndBit", ID_TYPE_FN_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +embed_function("ASin", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("ATan", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Bin$", ID_TYPE_FN_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("CInt32", ID_TYPE_FN_NUM); +add_embedded_arg("i", ID_TYPE_NUM); +embed_function("CInt64", ID_TYPE_FN_NUM); +add_embedded_arg("i", ID_TYPE_NUM); +embed_function("Cos", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Degrees", ID_TYPE_FN_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +embed_function("Exp", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Frac", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Hex$", ID_TYPE_FN_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("HexVal", ID_TYPE_FN_NUM); +add_embedded_arg("n$", ID_TYPE_STR); +embed_function("Int", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Log", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Max", ID_TYPE_FN_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +embed_function("Min", ID_TYPE_FN_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +embed_function("OrBit", ID_TYPE_FN_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +embed_function("Radians", ID_TYPE_FN_NUM); +add_embedded_arg("d", ID_TYPE_NUM); +embed_function("Randomize", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Rand", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Round", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Sign", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Sin", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Sqrt", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Tan", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("XOrBit", ID_TYPE_FN_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +embed_function("Asc", ID_TYPE_FN_NUM); +add_embedded_arg("c$", ID_TYPE_STR); +embed_function("Chr$", ID_TYPE_FN_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Insert$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("tgt$", ID_TYPE_STR); +add_embedded_arg("pos", ID_TYPE_NUM); +embed_function("InStr", ID_TYPE_FN_NUM); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("substr$", ID_TYPE_STR); +embed_function("LCase$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("Left$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Length", ID_TYPE_FN_NUM); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("Len", ID_TYPE_FN_NUM); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("LTrim$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("Mid$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("start", ID_TYPE_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("ReplaceSubstr$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("rpc$", ID_TYPE_STR); +add_embedded_arg("pos", ID_TYPE_NUM); +embed_function("Replace$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("tgt$", ID_TYPE_STR); +add_embedded_arg("rpc$", ID_TYPE_STR); +embed_function("Reverse$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("Right$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("RTrim$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("StringFill$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Str$", ID_TYPE_FN_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Str_F$", ID_TYPE_FN_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Str_S$", ID_TYPE_FN_STR); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Tally", ID_TYPE_FN_NUM); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("substr$", ID_TYPE_STR); +embed_function("Trim$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("UCase$", ID_TYPE_FN_STR); +add_embedded_arg("src$", ID_TYPE_STR); +embed_function("Val", ID_TYPE_FN_NUM); +add_embedded_arg("n$", ID_TYPE_STR); +embed_function("Stack_N", ID_TYPE_SUB); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Stack_S", ID_TYPE_SUB); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Push_N", ID_TYPE_SUB); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("Pop_N", ID_TYPE_FN_NUM); +embed_function("Push_S", ID_TYPE_SUB); +add_embedded_arg("s$", ID_TYPE_STR); +embed_function("Pop_S$", ID_TYPE_FN_STR); +embed_function("Stack_Size_N", ID_TYPE_FN_NUM); +embed_function("Stack_Size_S", ID_TYPE_FN_NUM); +embed_function("FileOpen", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("fileName$", ID_TYPE_STR); +add_embedded_arg("mode", ID_TYPE_NUM); +embed_function("FileClose", ID_TYPE_SUB); +add_embedded_arg("stream", ID_TYPE_NUM); +embed_function("ReadByte", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +embed_function("WriteByte", ID_TYPE_SUB); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("byte", ID_TYPE_NUM); +embed_function("ReadLine$", ID_TYPE_FN_STR); +add_embedded_arg("stream", ID_TYPE_NUM); +embed_function("Write", ID_TYPE_SUB); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("WriteLine", ID_TYPE_SUB); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("CopyFile", ID_TYPE_SUB); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("dst$", ID_TYPE_STR); +embed_function("RemoveFile", ID_TYPE_FN_NUM); +add_embedded_arg("fileName$", ID_TYPE_STR); +embed_function("FileExists", ID_TYPE_FN_NUM); +add_embedded_arg("fileName$", ID_TYPE_STR); +embed_function("MoveFile", ID_TYPE_FN_NUM); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("dst$", ID_TYPE_STR); +embed_function("RenameFile", ID_TYPE_FN_NUM); +add_embedded_arg("src$", ID_TYPE_STR); +add_embedded_arg("dst$", ID_TYPE_STR); +embed_function("FileLength", ID_TYPE_FN_NUM); +add_embedded_arg("fileName$", ID_TYPE_STR); +embed_function("Tell", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +embed_function("Seek", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("pos", ID_TYPE_NUM); +embed_function("EOF", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +embed_function("FreeFile", ID_TYPE_FN_NUM); +embed_function("ChangeDir", ID_TYPE_SUB); +add_embedded_arg("p$", ID_TYPE_STR); +embed_function("DirExists", ID_TYPE_FN_NUM); +add_embedded_arg("p$", ID_TYPE_STR); +embed_function("DirFirst$", ID_TYPE_FN_STR); +embed_function("Dir$", ID_TYPE_FN_STR); +embed_function("DirNext$", ID_TYPE_FN_STR); +embed_function("MakeDir", ID_TYPE_FN_NUM); +add_embedded_arg("p$", ID_TYPE_STR); +embed_function("RemoveDir", ID_TYPE_FN_NUM); +add_embedded_arg("p$", ID_TYPE_STR); +embed_function("Date$", ID_TYPE_FN_STR); +embed_function("Easter$", ID_TYPE_FN_STR); +add_embedded_arg("year", ID_TYPE_NUM); +embed_function("Ticks", ID_TYPE_FN_NUM); +embed_function("Time$", ID_TYPE_FN_STR); +embed_function("Timer", ID_TYPE_FN_NUM); +embed_function("Wait", ID_TYPE_SUB); +add_embedded_arg("m_sec", ID_TYPE_NUM); +embed_function("WindowOpen", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("title$", ID_TYPE_STR); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +add_embedded_arg("vsync", ID_TYPE_NUM); +embed_function("WindowClose", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("RaiseWindow", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("Window", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("Update", ID_TYPE_SUB); +embed_function("Cls", ID_TYPE_SUB); +embed_function("SetClearColor", ID_TYPE_SUB); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("ShowWindow", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("HideWindow", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("SetWindowTitle", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("title$", ID_TYPE_STR); +embed_function("WindowTitle$", ID_TYPE_FN_STR); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("SetWindowPosition", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("GetWindowPosition", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +embed_function("SetWindowSize", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("GetWindowSize", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("SetWindowMinSize", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("GetWindowMinSize", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("SetWindowMaxSize", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("GetWindowMaxSize", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("WindowIsFullscreen", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowIsVisible", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowIsBordered", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowIsResizable", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowIsMinimized", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowIsMaximized", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowHasInputFocus", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowHasMouseFocus", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("SetWindowFullscreen", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("MaximizeWindow", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("MinimizeWindow", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("SetWindowBorder", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("WindowClip", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("WindowExists", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("NumWindows", ID_TYPE_FN_NUM); +embed_function("WindowEvent_Close", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowEvent_Maximize", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("WindowEvent_Minimize", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("ActiveWindow", ID_TYPE_FN_NUM); +embed_function("FPS", ID_TYPE_FN_NUM); +embed_function("SetWindowIcon", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("CanvasOpen", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("viewport_x", ID_TYPE_NUM); +add_embedded_arg("viewport_y", ID_TYPE_NUM); +add_embedded_arg("viewport_w", ID_TYPE_NUM); +add_embedded_arg("viewport_h", ID_TYPE_NUM); +add_embedded_arg("mode", ID_TYPE_NUM); +embed_function("CanvasClose", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("SetCanvasVisible", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("CanvasIsVisible", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("SetCanvasViewport", ID_TYPE_SUB); +add_embedded_arg("cnum", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("GetCanvasViewport", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("Canvas", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("SetCanvasOffset", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("GetCanvasOffset", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +embed_function("GetCanvasSize", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("ClearCanvas", ID_TYPE_SUB); +embed_function("SetCanvasAlpha", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +embed_function("CanvasAlpha", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("SetCanvasBlendMode", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("blend_mode", ID_TYPE_NUM); +embed_function("CanvasBlendMode", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("SetCanvasColorMod", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("CanvasColorMod", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("CopyCanvas", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("dst", ID_TYPE_NUM); +add_embedded_arg("dx", ID_TYPE_NUM); +add_embedded_arg("dy", ID_TYPE_NUM); +embed_function("CloneCanvas", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_NUM); +add_embedded_arg("dst", ID_TYPE_NUM); +embed_function("SetCanvasZ", ID_TYPE_SUB); +add_embedded_arg("c_num", ID_TYPE_NUM); +add_embedded_arg("z", ID_TYPE_NUM); +embed_function("CanvasZ", ID_TYPE_FN_NUM); +add_embedded_arg("c_num", ID_TYPE_NUM); +embed_function("CanvasClip", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("ActiveCanvas", ID_TYPE_FN_NUM); +embed_function("Box", ID_TYPE_SUB); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +embed_function("BoxFill", ID_TYPE_SUB); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +embed_function("Circle", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("radius", ID_TYPE_NUM); +embed_function("CircleFill", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("radius", ID_TYPE_NUM); +embed_function("Ellipse", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("rx", ID_TYPE_NUM); +add_embedded_arg("ry", ID_TYPE_NUM); +embed_function("EllipseFill", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("rx", ID_TYPE_NUM); +add_embedded_arg("ry", ID_TYPE_NUM); +embed_function("FloodFill", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("GetPixel", ID_TYPE_FN_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("SetColor", ID_TYPE_SUB); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("Line", ID_TYPE_SUB); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +embed_function("Poly", ID_TYPE_SUB); +add_embedded_arg("n", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +embed_function("PolyFill", ID_TYPE_SUB); +add_embedded_arg("n", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +embed_function("Rect", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("RectFill", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("RoundRect", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +embed_function("RoundRectFill", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +embed_function("RGB", ID_TYPE_FN_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("g", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +embed_function("RGBA", ID_TYPE_FN_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("g", ID_TYPE_NUM); +add_embedded_arg("b", ID_TYPE_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +embed_function("PSet", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("LoadImage", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("img$", ID_TYPE_STR); +embed_function("LoadImage_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("img$", ID_TYPE_STR); +add_embedded_arg("colkey", ID_TYPE_NUM); +embed_function("ImageFromBuffer", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +embed_function("ImageFromBuffer_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +add_embedded_arg("colkey", ID_TYPE_NUM); +embed_function("BufferFromImage", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +embed_function("ImageExists", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("ColorKey", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("CopyImage", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_NUM); +add_embedded_arg("dst", ID_TYPE_NUM); +embed_function("DeleteImage", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("SetImageAlpha", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("a", ID_TYPE_NUM); +embed_function("ImageAlpha", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("GetImageSize", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("SetImageBlendMode", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("blend_mode", ID_TYPE_NUM); +embed_function("ImageBlendMode", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("SetImageColorMod", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("ImageColorMod", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("DrawImage", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("DrawImage_Blit", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +embed_function("DrawImage_Blit_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +embed_function("DrawImage_Rotate", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("angle", ID_TYPE_NUM); +embed_function("DrawImage_Rotate_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +add_embedded_arg("angle", ID_TYPE_NUM); +embed_function("DrawImage_Zoom", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("zx", ID_TYPE_NUM); +add_embedded_arg("zy", ID_TYPE_NUM); +embed_function("DrawImage_Zoom_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +add_embedded_arg("zx", ID_TYPE_NUM); +add_embedded_arg("zy", ID_TYPE_NUM); +embed_function("DrawImage_Rotozoom", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("angle", ID_TYPE_NUM); +add_embedded_arg("zx", ID_TYPE_NUM); +add_embedded_arg("zy", ID_TYPE_NUM); +embed_function("DrawImage_Rotozoom_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +add_embedded_arg("angle", ID_TYPE_NUM); +add_embedded_arg("zx", ID_TYPE_NUM); +add_embedded_arg("zy", ID_TYPE_NUM); +embed_function("DrawImage_Flip", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("v", ID_TYPE_NUM); +embed_function("DrawImage_Flip_Ex", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("v", ID_TYPE_NUM); +embed_function("InKey", ID_TYPE_FN_NUM); +embed_function("Key", ID_TYPE_FN_NUM); +add_embedded_arg("key_code", ID_TYPE_NUM); +embed_function("WaitKey", ID_TYPE_FN_NUM); +embed_function("HideMouse", ID_TYPE_SUB); +embed_function("ShowMouse", ID_TYPE_SUB); +embed_function("MouseIsVisible", ID_TYPE_FN_NUM); +embed_function("GetMouse", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("mb1", ID_TYPE_BYREF_NUM); +add_embedded_arg("mb2", ID_TYPE_BYREF_NUM); +add_embedded_arg("mb3", ID_TYPE_BYREF_NUM); +embed_function("MouseX", ID_TYPE_FN_NUM); +embed_function("MouseY", ID_TYPE_FN_NUM); +embed_function("MouseButton", ID_TYPE_FN_NUM); +add_embedded_arg("mb", ID_TYPE_NUM); +embed_function("GetMouseWheel", ID_TYPE_SUB); +add_embedded_arg("x_axis", ID_TYPE_BYREF_NUM); +add_embedded_arg("y_axis", ID_TYPE_BYREF_NUM); +embed_function("MouseWheelX", ID_TYPE_FN_NUM); +embed_function("MouseWheelY", ID_TYPE_FN_NUM); +embed_function("SoundFromBuffer", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +add_embedded_arg("buffer_size", ID_TYPE_NUM); +add_embedded_arg("vol", ID_TYPE_NUM); +embed_function("LoadSound", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("snd_file$", ID_TYPE_STR); +embed_function("LoadMusic", ID_TYPE_SUB); +add_embedded_arg("music_file$", ID_TYPE_STR); +embed_function("PlaySound", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +add_embedded_arg("loops", ID_TYPE_NUM); +embed_function("PlaySoundTimed", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +add_embedded_arg("loops", ID_TYPE_NUM); +add_embedded_arg("ms", ID_TYPE_NUM); +embed_function("PlayMusic", ID_TYPE_SUB); +add_embedded_arg("mLoops", ID_TYPE_NUM); +embed_function("PauseSound", ID_TYPE_SUB); +add_embedded_arg("channel", ID_TYPE_NUM); +embed_function("ResumeSound", ID_TYPE_SUB); +add_embedded_arg("channel", ID_TYPE_NUM); +embed_function("PauseMusic", ID_TYPE_SUB); +embed_function("ResumeMusic", ID_TYPE_SUB); +embed_function("DeleteSound", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("DeleteMusic", ID_TYPE_SUB); +embed_function("FadeMusicIn", ID_TYPE_SUB); +add_embedded_arg("fade_time", ID_TYPE_NUM); +add_embedded_arg("loops", ID_TYPE_NUM); +embed_function("FadeMusicOut", ID_TYPE_SUB); +add_embedded_arg("fade_time", ID_TYPE_NUM); +embed_function("MusicExists", ID_TYPE_FN_NUM); +embed_function("SetMusicVolume", ID_TYPE_SUB); +add_embedded_arg("vol", ID_TYPE_NUM); +embed_function("MusicVolume", ID_TYPE_FN_NUM); +embed_function("SetMusicPosition", ID_TYPE_SUB); +add_embedded_arg("pos", ID_TYPE_NUM); +embed_function("MusicPosition", ID_TYPE_FN_NUM); +embed_function("RewindMusic", ID_TYPE_SUB); +embed_function("SetSoundChannels", ID_TYPE_SUB); +add_embedded_arg("max_channels", ID_TYPE_NUM); +embed_function("NumSoundChannels", ID_TYPE_FN_NUM); +embed_function("SoundIsEnabled", ID_TYPE_FN_NUM); +embed_function("SoundExists", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("SetChannelVolume", ID_TYPE_SUB); +add_embedded_arg("channel", ID_TYPE_NUM); +add_embedded_arg("vol", ID_TYPE_NUM); +embed_function("ChannelVolume", ID_TYPE_FN_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +embed_function("SetSoundVolume", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("vol", ID_TYPE_NUM); +embed_function("SoundVolume", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("StopMusic", ID_TYPE_SUB); +embed_function("StopSound", ID_TYPE_SUB); +add_embedded_arg("channel", ID_TYPE_NUM); +embed_function("SetChannelPanning", ID_TYPE_FN_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +add_embedded_arg("left_value", ID_TYPE_NUM); +add_embedded_arg("right_value", ID_TYPE_NUM); +embed_function("SetChannelDistance", ID_TYPE_FN_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +add_embedded_arg("dist_value", ID_TYPE_NUM); +embed_function("ChannelIsPlaying", ID_TYPE_FN_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +embed_function("ChannelIsPaused", ID_TYPE_FN_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +embed_function("NumJoysticks", ID_TYPE_FN_NUM); +embed_function("NumJoyAxes", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("NumJoyButtons", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("NumJoyHats", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("NumJoyTrackBalls", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("JoyAxis", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +add_embedded_arg("joy_axis", ID_TYPE_NUM); +embed_function("JoyButton", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +add_embedded_arg("joy_button", ID_TYPE_NUM); +embed_function("JoyHat", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +add_embedded_arg("joy_hat", ID_TYPE_NUM); +embed_function("GetJoyTrackBall", ID_TYPE_SUB); +add_embedded_arg("joy_num", ID_TYPE_NUM); +add_embedded_arg("ball", ID_TYPE_NUM); +add_embedded_arg("dx", ID_TYPE_BYREF_NUM); +add_embedded_arg("dy", ID_TYPE_BYREF_NUM); +embed_function("JoyName$", ID_TYPE_FN_STR); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("JoystickIsConnected", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("GetCursor", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +embed_function("PrintS", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("InputS$", ID_TYPE_FN_STR); +add_embedded_arg("prompt$", ID_TYPE_STR); +embed_function("ZoneInputS$", ID_TYPE_FN_STR); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("Locate", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("ReadInput_Start", ID_TYPE_SUB); +embed_function("ReadInput_Stop", ID_TYPE_SUB); +embed_function("ReadInput_Text$", ID_TYPE_FN_STR); +embed_function("ReadInput_SetText", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("ReadInput_ToggleBackspace", ID_TYPE_SUB); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("LoadFont", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("fnt_file$", ID_TYPE_STR); +add_embedded_arg("size", ID_TYPE_NUM); +embed_function("DeleteFont", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("FontIsLoaded", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("Font", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +embed_function("SetFontStyle", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("style", ID_TYPE_NUM); +embed_function("DrawText", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("DrawText_Shaded", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("fg_color", ID_TYPE_NUM); +add_embedded_arg("bg_color", ID_TYPE_NUM); +embed_function("DrawText_Blended", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("RenderText", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("GetTextSize", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("txt$", ID_TYPE_STR); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("TouchPressure", ID_TYPE_FN_NUM); +embed_function("GetTouch", ID_TYPE_SUB); +add_embedded_arg("status", ID_TYPE_BYREF_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("dx", ID_TYPE_BYREF_NUM); +add_embedded_arg("dy", ID_TYPE_BYREF_NUM); +embed_function("GetMultiTouch", ID_TYPE_SUB); +add_embedded_arg("status", ID_TYPE_BYREF_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("fingers", ID_TYPE_BYREF_NUM); +add_embedded_arg("dist", ID_TYPE_BYREF_NUM); +add_embedded_arg("theta", ID_TYPE_BYREF_NUM); +embed_function("GetTouchFinger", ID_TYPE_SUB); +add_embedded_arg("finger", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("pressure", ID_TYPE_BYREF_NUM); +embed_function("NumFingers", ID_TYPE_FN_NUM); +embed_function("CheckSockets", ID_TYPE_FN_NUM); +add_embedded_arg("timeout_ms", ID_TYPE_NUM); +embed_function("TCP_SocketReady", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("UDP_SocketReady", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("TCP_SocketOpen", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +add_embedded_arg("host$", ID_TYPE_STR); +add_embedded_arg("port", ID_TYPE_NUM); +embed_function("TCP_SocketClose", ID_TYPE_SUB); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("TCP_RemoteHost", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("TCP_RemotePort", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("TCP_GetData", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +add_embedded_arg("sData$", ID_TYPE_BYREF_STR); +add_embedded_arg("numBytes", ID_TYPE_NUM); +embed_function("TCP_SendData", ID_TYPE_SUB); +add_embedded_arg("socket", ID_TYPE_NUM); +add_embedded_arg("sData$", ID_TYPE_STR); +embed_function("TCP_AcceptSocket", ID_TYPE_FN_NUM); +add_embedded_arg("server", ID_TYPE_NUM); +add_embedded_arg("client", ID_TYPE_NUM); +embed_function("UDP_SocketOpen", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +add_embedded_arg("port", ID_TYPE_NUM); +embed_function("UDP_SocketClose", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("UDP_GetData", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +add_embedded_arg("sData$", ID_TYPE_BYREF_STR); +add_embedded_arg("host$", ID_TYPE_BYREF_STR); +add_embedded_arg("port", ID_TYPE_BYREF_NUM); +embed_function("UDP_Length", ID_TYPE_FN_NUM); +embed_function("UDP_MaxLength", ID_TYPE_FN_NUM); +embed_function("UDP_RemoteHost$", ID_TYPE_FN_STR); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("UDP_RemotePort", ID_TYPE_FN_NUM); +add_embedded_arg("socket", ID_TYPE_NUM); +embed_function("UDP_SendData", ID_TYPE_SUB); +add_embedded_arg("socket", ID_TYPE_NUM); +add_embedded_arg("sData$", ID_TYPE_STR); +add_embedded_arg("host$", ID_TYPE_STR); +add_embedded_arg("port", ID_TYPE_NUM); +embed_function("LoadVideo", ID_TYPE_SUB); +add_embedded_arg("vid$", ID_TYPE_STR); +embed_function("PlayVideo", ID_TYPE_SUB); +add_embedded_arg("vLoops", ID_TYPE_NUM); +embed_function("PauseVideo", ID_TYPE_SUB); +embed_function("StopVideo", ID_TYPE_SUB); +embed_function("SetVideoPosition", ID_TYPE_SUB); +add_embedded_arg("pos", ID_TYPE_NUM); +embed_function("ResumeVideo", ID_TYPE_SUB); +embed_function("VideoPosition", ID_TYPE_FN_NUM); +embed_function("DeleteVideo", ID_TYPE_SUB); +embed_function("VideoIsPlaying", ID_TYPE_FN_NUM); +embed_function("VideoEnd", ID_TYPE_FN_NUM); +embed_function("GetVideoStats", ID_TYPE_SUB); +add_embedded_arg("vFile$", ID_TYPE_STR); +add_embedded_arg("vLen", ID_TYPE_BYREF_NUM); +add_embedded_arg("vfps", ID_TYPE_BYREF_NUM); +add_embedded_arg("frame_w", ID_TYPE_BYREF_NUM); +add_embedded_arg("frame_h", ID_TYPE_BYREF_NUM); +embed_function("SetVideoDrawRect", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("GetVideoDrawRect", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("GetVideoSize", ID_TYPE_SUB); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +embed_function("VideoExists", ID_TYPE_FN_NUM); +embed_function("SetVideoAlpha", ID_TYPE_SUB); +add_embedded_arg("a", ID_TYPE_NUM); +embed_function("System", ID_TYPE_FN_NUM); +add_embedded_arg("cmd$", ID_TYPE_STR); +embed_function("OS$", ID_TYPE_FN_STR); +embed_function("Command$", ID_TYPE_FN_STR); +add_embedded_arg("arg", ID_TYPE_NUM); +embed_function("NumCommands", ID_TYPE_FN_NUM); +embed_function("Env$", ID_TYPE_FN_STR); +add_embedded_arg("v$", ID_TYPE_STR); +embed_function("SetEnv", ID_TYPE_SUB); +add_embedded_arg("var$", ID_TYPE_STR); +add_embedded_arg("value$", ID_TYPE_STR); +add_embedded_arg("overwrite", ID_TYPE_NUM); +embed_function("PrefPath$", ID_TYPE_FN_STR); +add_embedded_arg("org_name$", ID_TYPE_STR); +add_embedded_arg("app_name$", ID_TYPE_STR); +embed_function("Android_GetExternalStoragePath$", ID_TYPE_FN_STR); +embed_function("Android_GetExternalStorageState", ID_TYPE_FN_NUM); +embed_function("Android_GetInternalStoragePath$", ID_TYPE_FN_STR); +embed_function("Android_JNI_Message$", ID_TYPE_FN_STR); +add_embedded_arg("arg$", ID_TYPE_STR); +embed_function("Runtime_Utility_Message$", ID_TYPE_FN_STR); +add_embedded_arg("arg$", ID_TYPE_STR); +embed_function("ClipboardText$", ID_TYPE_FN_STR); +embed_function("SetClipboardText", ID_TYPE_SUB); +add_embedded_arg("txt$", ID_TYPE_STR); +embed_function("HasClipboardText", ID_TYPE_FN_NUM); +embed_function("GetDesktopDisplayMode", ID_TYPE_SUB); +add_embedded_arg("index", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_BYREF_NUM); +add_embedded_arg("h", ID_TYPE_BYREF_NUM); +add_embedded_arg("freq", ID_TYPE_BYREF_NUM); +embed_function("DrawImage_Transform", ID_TYPE_SUB); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +add_embedded_arg("src_x", ID_TYPE_NUM); +add_embedded_arg("src_y", ID_TYPE_NUM); +add_embedded_arg("src_w", ID_TYPE_NUM); +add_embedded_arg("src_h", ID_TYPE_NUM); +add_embedded_arg("angle", ID_TYPE_NUM); +add_embedded_arg("center_x", ID_TYPE_NUM); +add_embedded_arg("center_y", ID_TYPE_NUM); +add_embedded_arg("flip_h", ID_TYPE_NUM); +add_embedded_arg("flip_v", ID_TYPE_NUM); +embed_function("GetPowerInfo", ID_TYPE_SUB); +add_embedded_arg("status", ID_TYPE_BYREF_NUM); +add_embedded_arg("secs", ID_TYPE_BYREF_NUM); +add_embedded_arg("pct", ID_TYPE_BYREF_NUM); +embed_function("SystemRam", ID_TYPE_FN_NUM); +embed_function("SetRenderScaleQuality", ID_TYPE_FN_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("EvalJS$", ID_TYPE_FN_STR); +add_embedded_arg("js_code$", ID_TYPE_STR); +embed_function("GetRenderScaleQuality", ID_TYPE_FN_NUM); +embed_function("GetGlobalMouse", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("mb1", ID_TYPE_BYREF_NUM); +add_embedded_arg("mb2", ID_TYPE_BYREF_NUM); +add_embedded_arg("mb3", ID_TYPE_BYREF_NUM); +embed_function("GlobalMouseX", ID_TYPE_FN_NUM); +embed_function("GlobalMouseY", ID_TYPE_FN_NUM); +embed_function("GetAccel", ID_TYPE_SUB); +add_embedded_arg("accel_num", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("z", ID_TYPE_BYREF_NUM); +embed_function("AccelName$", ID_TYPE_FN_STR); +add_embedded_arg("accel_num", ID_TYPE_NUM); +embed_function("NumAccels", ID_TYPE_FN_NUM); +embed_function("GetGyro", ID_TYPE_SUB); +add_embedded_arg("gyro_num", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_BYREF_NUM); +add_embedded_arg("y", ID_TYPE_BYREF_NUM); +add_embedded_arg("z", ID_TYPE_BYREF_NUM); +embed_function("GyroName$", ID_TYPE_FN_STR); +add_embedded_arg("gyro_num", ID_TYPE_NUM); +embed_function("NumGyros", ID_TYPE_FN_NUM); +embed_function("JoyRumblePlay", ID_TYPE_SUB); +add_embedded_arg("joy_num", ID_TYPE_NUM); +add_embedded_arg("strength", ID_TYPE_NUM); +add_embedded_arg("duration", ID_TYPE_NUM); +embed_function("JoyRumbleStop", ID_TYPE_SUB); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("JoystickIsHaptic", ID_TYPE_FN_NUM); +add_embedded_arg("joy_num", ID_TYPE_NUM); +embed_function("WriteByteBuffer", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("buf", ID_TYPE_BYREF_NUM); +add_embedded_arg("buf_size", ID_TYPE_NUM); +embed_function("ReadByteBuffer", ID_TYPE_FN_NUM); +add_embedded_arg("stream", ID_TYPE_NUM); +add_embedded_arg("buf", ID_TYPE_BYREF_NUM); +add_embedded_arg("buf_size", ID_TYPE_NUM); +embed_function("WindowEvent_Resize", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("SetWindowAutoClose", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("exit_on_close", ID_TYPE_NUM); +embed_function("SetWindowResizable", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("SystemReturnStdOut$", ID_TYPE_FN_STR); +add_embedded_arg("cmd$", ID_TYPE_STR); +embed_function("WindowMode", ID_TYPE_FN_NUM); +add_embedded_arg("visible", ID_TYPE_NUM); +add_embedded_arg("fullscreen", ID_TYPE_NUM); +add_embedded_arg("resizable", ID_TYPE_NUM); +add_embedded_arg("borderless", ID_TYPE_NUM); +add_embedded_arg("highDPI", ID_TYPE_NUM); +embed_function("WindowFlags", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("RestoreWindow", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("UpdateAllWindows", ID_TYPE_SUB); +embed_function("QueryAudioSpec", ID_TYPE_FN_NUM); +add_embedded_arg("freq", ID_TYPE_BYREF_NUM); +add_embedded_arg("format", ID_TYPE_BYREF_NUM); +add_embedded_arg("channels", ID_TYPE_BYREF_NUM); +embed_function("MusicIsPlaying", ID_TYPE_FN_NUM); +embed_function("DrawGeometry", ID_TYPE_FN_NUM); +add_embedded_arg("slot", ID_TYPE_NUM); +add_embedded_arg("num_vertices", ID_TYPE_NUM); +add_embedded_arg("vertices", ID_TYPE_BYREF_NUM); +add_embedded_arg("num_indices", ID_TYPE_NUM); +add_embedded_arg("Indices", ID_TYPE_BYREF_NUM); +embed_function("Size", ID_TYPE_FN_NUM); +add_embedded_arg("s$", ID_TYPE_STR); +embed_function("BufferFromString", ID_TYPE_FN_NUM); +add_embedded_arg("s$", ID_TYPE_STR); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +embed_function("StringFromBuffer$", ID_TYPE_FN_STR); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +add_embedded_arg("buffer_size", ID_TYPE_NUM); +embed_function("GrabInput", ID_TYPE_SUB); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("GrabbedWindow", ID_TYPE_FN_NUM); +embed_function("WarpMouse", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("WarpMouseGlobal", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +embed_function("SetMouseZone", ID_TYPE_SUB); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("w", ID_TYPE_NUM); +add_embedded_arg("h", ID_TYPE_NUM); +embed_function("ClearMouseZone", ID_TYPE_SUB); +embed_function("SetWindowAlwaysOnTop", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("SetMouseRelative", ID_TYPE_SUB); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("SetWindowVSync", ID_TYPE_SUB); +add_embedded_arg("win", ID_TYPE_NUM); +add_embedded_arg("flag", ID_TYPE_NUM); +embed_function("OpenURL", ID_TYPE_FN_NUM); +add_embedded_arg("url$", ID_TYPE_STR); +embed_function("APIVersion$", ID_TYPE_FN_STR); +embed_function("FlashWindow", ID_TYPE_FN_NUM); +add_embedded_arg("win", ID_TYPE_NUM); +embed_function("MessageBox", ID_TYPE_FN_NUM); +add_embedded_arg("title$", ID_TYPE_STR); +add_embedded_arg("msg$", ID_TYPE_STR); +embed_function("NumberArrayCopy", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_BYREF_NUM); +add_embedded_arg("dst", ID_TYPE_BYREF_NUM); +embed_function("StringArrayCopy", ID_TYPE_SUB); +add_embedded_arg("src$", ID_TYPE_BYREF_STR); +add_embedded_arg("dst$", ID_TYPE_BYREF_STR); +embed_function("ArrayCopy", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_BYREF_NUM); +add_embedded_arg("dst", ID_TYPE_BYREF_NUM); +embed_function("NumberArrayFill", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_BYREF_NUM); +add_embedded_arg("fdata", ID_TYPE_NUM); +embed_function("StringArrayFill", ID_TYPE_SUB); +add_embedded_arg("src$", ID_TYPE_BYREF_STR); +add_embedded_arg("fdata$", ID_TYPE_STR); +embed_function("ArrayFill", ID_TYPE_SUB); +add_embedded_arg("src", ID_TYPE_BYREF_NUM); +add_embedded_arg("fdata", ID_TYPE_NUM); +embed_function("Runtime$", ID_TYPE_FN_STR); +embed_function("DimMatrix", ID_TYPE_SUB); +add_embedded_arg("m", ID_TYPE_NUM); +add_embedded_arg("m_rows", ID_TYPE_NUM); +add_embedded_arg("m_cols", ID_TYPE_NUM); +add_embedded_arg("preserve_flag", ID_TYPE_NUM); +embed_function("AddMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("AugmentMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("CopyMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("InsertMatrixColumns", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +embed_function("InsertMatrixRows", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +embed_function("MultiplyMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("CubeMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("DeleteMatrixColumns", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +embed_function("DeleteMatrixRows", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +embed_function("ClearMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +embed_function("ClearMatrixColumns", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +embed_function("ClearMatrixRows", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +embed_function("FillMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("v", ID_TYPE_NUM); +embed_function("FillMatrixColumns", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +add_embedded_arg("v", ID_TYPE_NUM); +embed_function("FillMatrixRows", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +add_embedded_arg("v", ID_TYPE_NUM); +embed_function("CopyMatrixColumns", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +embed_function("CopyMatrixRows", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +embed_function("IdentityMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("n", ID_TYPE_NUM); +embed_function("SolveMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("IsEqualMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("tolerance", ID_TYPE_NUM); +embed_function("Determinant", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +embed_function("AdjointMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("InvertMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("MatrixFromBuffer", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +embed_function("GetMatrix", ID_TYPE_SUB); +add_embedded_arg("buffer", ID_TYPE_BYREF_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +embed_function("RandomizeMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("vmin", ID_TYPE_NUM); +add_embedded_arg("vmax", ID_TYPE_NUM); +embed_function("MatrixValue", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("SetMatrixValue", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("v", ID_TYPE_NUM); +embed_function("ScalarMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("s_value", ID_TYPE_NUM); +embed_function("ScalarMatrixColumns", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +add_embedded_arg("s_value", ID_TYPE_NUM); +embed_function("ScalarMatrixRows", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +add_embedded_arg("s_value", ID_TYPE_NUM); +embed_function("SquareMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("SubMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +embed_function("SubtractMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("SwapMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("SwapMatrixColumn", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("C1", ID_TYPE_NUM); +add_embedded_arg("C2", ID_TYPE_NUM); +embed_function("SwapMatrixRow", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("R1", ID_TYPE_NUM); +add_embedded_arg("R2", ID_TYPE_NUM); +embed_function("TransposeMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +embed_function("UnAugmentMatrix", ID_TYPE_FN_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("ZeroMatrix", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +embed_function("GetMatrixSize", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_BYREF_NUM); +add_embedded_arg("c", ID_TYPE_BYREF_NUM); +embed_function("SetMatrixProcess", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessOpen", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("SetProcessErrorMode", ID_TYPE_SUB); +add_embedded_arg("p_num", ID_TYPE_NUM); +add_embedded_arg("error_mode", ID_TYPE_NUM); +embed_function("ProcessError", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessWait", ID_TYPE_SUB); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessWaitAll", ID_TYPE_SUB); +embed_function("ProcessContinue", ID_TYPE_SUB); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessStop", ID_TYPE_SUB); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessClear", ID_TYPE_SUB); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessClose", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessErrorMode", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessSleep", ID_TYPE_SUB); +add_embedded_arg("p_num", ID_TYPE_NUM); +add_embedded_arg("msec", ID_TYPE_NUM); +embed_function("ProcessExists", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("ProcessStopAll", ID_TYPE_SUB); +embed_function("ProcessContinueAll", ID_TYPE_SUB); +embed_function("ProcessQueueSize", ID_TYPE_FN_NUM); +add_embedded_arg("p_num", ID_TYPE_NUM); +embed_function("NumCPUs", ID_TYPE_FN_NUM); +embed_function("GetProjectionGeometry", ID_TYPE_SUB); +add_embedded_arg("cam_dist", ID_TYPE_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("f_vertex_count", ID_TYPE_NUM); +add_embedded_arg("columns", ID_TYPE_BYREF_NUM); +add_embedded_arg("uv", ID_TYPE_BYREF_NUM); +add_embedded_arg("graph_offset_x", ID_TYPE_NUM); +add_embedded_arg("graph_offset_y", ID_TYPE_NUM); +add_embedded_arg("v_color", ID_TYPE_NUM); +add_embedded_arg("vertex_count", ID_TYPE_BYREF_NUM); +add_embedded_arg("vertex2D", ID_TYPE_BYREF_NUM); +add_embedded_arg("index_count", ID_TYPE_BYREF_NUM); +add_embedded_arg("index", ID_TYPE_BYREF_NUM); +add_embedded_arg("clip_dist", ID_TYPE_BYREF_NUM); +add_embedded_arg("min_x", ID_TYPE_BYREF_NUM); +add_embedded_arg("min_y", ID_TYPE_BYREF_NUM); +add_embedded_arg("max_x", ID_TYPE_BYREF_NUM); +add_embedded_arg("max_y", ID_TYPE_BYREF_NUM); +embed_function("CalculateFaceZ", ID_TYPE_FN_NUM); +add_embedded_arg("cam_dist", ID_TYPE_NUM); +add_embedded_arg("graph_offset_x", ID_TYPE_NUM); +add_embedded_arg("graph_offset_y", ID_TYPE_NUM); +add_embedded_arg("view_w", ID_TYPE_NUM); +add_embedded_arg("view_h", ID_TYPE_NUM); +add_embedded_arg("view_depth", ID_TYPE_NUM); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("f_vertex_count", ID_TYPE_NUM); +add_embedded_arg("columns", ID_TYPE_BYREF_NUM); +add_embedded_arg("face_min_z", ID_TYPE_BYREF_NUM); +add_embedded_arg("face_max_z", ID_TYPE_BYREF_NUM); +add_embedded_arg("z_avg", ID_TYPE_BYREF_NUM); +embed_function("SetChannelSpacePosition", ID_TYPE_FN_NUM); +add_embedded_arg("channel", ID_TYPE_NUM); +add_embedded_arg("angle", ID_TYPE_NUM); +add_embedded_arg("distance", ID_TYPE_NUM); +embed_function("SaveBMP", ID_TYPE_FN_NUM); +add_embedded_arg("img", ID_TYPE_NUM); +add_embedded_arg("file$", ID_TYPE_STR); +embed_function("SavePNG", ID_TYPE_FN_NUM); +add_embedded_arg("img", ID_TYPE_NUM); +add_embedded_arg("file$", ID_TYPE_STR); +embed_function("SaveJPG", ID_TYPE_FN_NUM); +add_embedded_arg("img", ID_TYPE_NUM); +add_embedded_arg("file$", ID_TYPE_STR); +embed_function("GetLineIntersection", ID_TYPE_FN_NUM); +add_embedded_arg("p0_x", ID_TYPE_NUM); +add_embedded_arg("p0_y", ID_TYPE_NUM); +add_embedded_arg("p1_x", ID_TYPE_NUM); +add_embedded_arg("p1_y", ID_TYPE_NUM); +add_embedded_arg("p2_x", ID_TYPE_NUM); +add_embedded_arg("p2_y", ID_TYPE_NUM); +add_embedded_arg("p3_x", ID_TYPE_NUM); +add_embedded_arg("p3_y", ID_TYPE_NUM); +add_embedded_arg("i_x", ID_TYPE_BYREF_NUM); +add_embedded_arg("i_y", ID_TYPE_BYREF_NUM); +embed_function("Interpolate", ID_TYPE_FN_NUM); +add_embedded_arg("min_a", ID_TYPE_NUM); +add_embedded_arg("max_a", ID_TYPE_NUM); +add_embedded_arg("mid_a", ID_TYPE_NUM); +add_embedded_arg("min_b", ID_TYPE_NUM); +add_embedded_arg("max_b", ID_TYPE_NUM); +embed_function("ATan2", ID_TYPE_FN_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +embed_function("PointInQuad", ID_TYPE_FN_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +add_embedded_arg("x3", ID_TYPE_NUM); +add_embedded_arg("y3", ID_TYPE_NUM); +add_embedded_arg("x4", ID_TYPE_NUM); +add_embedded_arg("y4", ID_TYPE_NUM); +embed_function("PointInTri", ID_TYPE_FN_NUM); +add_embedded_arg("x", ID_TYPE_NUM); +add_embedded_arg("y", ID_TYPE_NUM); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +add_embedded_arg("x3", ID_TYPE_NUM); +add_embedded_arg("y3", ID_TYPE_NUM); +embed_function("Distance2D", ID_TYPE_FN_NUM); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +embed_function("Distance3D", ID_TYPE_FN_NUM); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("z1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +add_embedded_arg("z2", ID_TYPE_NUM); +embed_function("GetCircleLineIntersection", ID_TYPE_FN_NUM); +add_embedded_arg("circle_x", ID_TYPE_NUM); +add_embedded_arg("circle_y", ID_TYPE_NUM); +add_embedded_arg("radius", ID_TYPE_NUM); +add_embedded_arg("x1", ID_TYPE_NUM); +add_embedded_arg("y1", ID_TYPE_NUM); +add_embedded_arg("x2", ID_TYPE_NUM); +add_embedded_arg("y2", ID_TYPE_NUM); +add_embedded_arg("ix1", ID_TYPE_BYREF_NUM); +add_embedded_arg("iy1", ID_TYPE_BYREF_NUM); +add_embedded_arg("ix2", ID_TYPE_BYREF_NUM); +add_embedded_arg("iy2", ID_TYPE_BYREF_NUM); +embed_function("GetLinePlaneIntersection", ID_TYPE_FN_NUM); +add_embedded_arg("line_point", ID_TYPE_BYREF_NUM); +add_embedded_arg("line_direction", ID_TYPE_BYREF_NUM); +add_embedded_arg("plane_point_1", ID_TYPE_BYREF_NUM); +add_embedded_arg("plane_point_2", ID_TYPE_BYREF_NUM); +add_embedded_arg("plane_point_3", ID_TYPE_BYREF_NUM); +add_embedded_arg("intersection", ID_TYPE_BYREF_NUM); +embed_function("IncrementMatrixRows", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("r", ID_TYPE_NUM); +add_embedded_arg("num_rows", ID_TYPE_NUM); +add_embedded_arg("value", ID_TYPE_NUM); +embed_function("IncrementMatrixColumns", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("c", ID_TYPE_NUM); +add_embedded_arg("num_cols", ID_TYPE_NUM); +add_embedded_arg("value", ID_TYPE_NUM); +embed_function("JoinMatrixRows", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); +embed_function("JoinMatrixColumns", ID_TYPE_SUB); +add_embedded_arg("mA", ID_TYPE_NUM); +add_embedded_arg("mB", ID_TYPE_NUM); +add_embedded_arg("mC", ID_TYPE_NUM); + +} + + +#endif // RC_BUILTIN_H_INCLUDED diff --git a/rcbasic_build/rc_debug.h b/rcbasic_build/rc_debug.h new file mode 100644 index 0000000..9a46a91 --- /dev/null +++ b/rcbasic_build/rc_debug.h @@ -0,0 +1,20 @@ +#ifndef RC_DEBUG_H_INCLUDED +#define RC_DEBUG_H_INCLUDED + +using namespace std; + +string ERROR_MSG = ""; + +void rc_setError(string rc_error) +{ + ERROR_MSG += rc_error + "\n"; +} + +string rc_getError() +{ + string error_out = ERROR_MSG; + //ERROR_MSG = ""; + return error_out; +} + +#endif // RC_DEBUG_H_INCLUDED diff --git a/rcbasic_build/rc_global.h b/rcbasic_build/rc_global.h new file mode 100644 index 0000000..688837f --- /dev/null +++ b/rcbasic_build/rc_global.h @@ -0,0 +1,213 @@ +#ifndef RC_GLOBAL_INCLUDED +#define RC_GLOBAL_INCLUDED +#include + +#define CODE_SEGMENT 0 +#define DATA_SEGMENT 1 + +struct rc_label +{ + string label_name=""; + uint64_t label_address=0; + int label_segment = 0; +}; + +class rc_vm_asm +{ +public: + vector vm_code; + vector label; + int current_segment = 0; + uint64_t current_address[2]; + uint64_t n_stack_count = 0; + uint64_t s_stack_count = 0; + uint64_t u_stack_count = 0; + uint64_t max_n_stack_count = 0; + uint64_t max_s_stack_count = 0; + uint64_t max_u_stack_count = 0; + + void push_back(string s) + { + s += " "; + vm_code.push_back(s); + if(s.substr(0,s.find_first_of(" ")).compare(".code")==0) + { + current_segment = CODE_SEGMENT; + } + else if(s.substr(0,s.find_first_of(" ")).compare(".data")==0) + { + //cout << "got data son" << endl; + current_segment = DATA_SEGMENT; + } + else if(s.substr(0,s.find_first_of(" ")).compare("label")==0) + { + rc_label current_label; + s = s.substr(s.find_first_of(" ")); + s = s.substr(s.find_first_not_of(" ")); + current_label.label_name = s; + current_label.label_address = current_address[current_segment]; + current_label.label_segment = current_segment; + //cout << "got a mutha flippin label: " << current_label.label_name << " : " << current_label.label_segment << endl; + label.push_back(current_label); + } + else if(s.substr(0,s.find_first_of(" ")).compare("mov")==0 || s.substr(0,s.find_first_of(" ")).compare("mov$")==0 || + s.substr(0,s.find_first_of(" ")).compare("mov_r")==0 || s.substr(0,s.find_first_of(" ")).compare("mov_r$")==0 || + s.substr(0,s.find_first_of(" ")).compare("mov_type")==0 || s.substr(0,s.find_first_of(" ")).compare("add$")==0 || + s.substr(0,s.find_first_of(" ")).compare("add")==0 || s.substr(0,s.find_first_of(" ")).compare("sub")==0 || + s.substr(0,s.find_first_of(" ")).compare("mul")==0 || s.substr(0,s.find_first_of(" ")).compare("div")==0 || + s.substr(0,s.find_first_of(" ")).compare("pow")==0 || s.substr(0,s.find_first_of(" ")).compare("mod")==0 || + s.substr(0,s.find_first_of(" ")).compare("shl")==0 || s.substr(0,s.find_first_of(" ")).compare("shr")==0 || + s.substr(0,s.find_first_of(" ")).compare("and")==0 || s.substr(0,s.find_first_of(" ")).compare("or")==0 || + s.substr(0,s.find_first_of(" ")).compare("xor")==0 || s.substr(0,s.find_first_of(" ")).compare("mov_arr$")==0 || + s.substr(0,s.find_first_of(" ")).compare("cmp")==0 || s.substr(0,s.find_first_of(" ")).compare("cmp$")==0 || + s.substr(0,s.find_first_of(" ")).compare("cmp_u")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_num1")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_str1")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr1")==0 || + s.substr(0,s.find_first_of(" ")).compare("dim_type")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_num1")==0 || + s.substr(0,s.find_first_of(" ")).compare("dim_str1")==0 || s.substr(0,s.find_first_of(" ")).compare("loop_while")==0 || + s.substr(0,s.find_first_of(" ")).compare("loop_until")==0 || + s.substr(0,s.find_first_of(" ")).compare("while")==0 || s.substr(0,s.find_first_of(" ")).compare("mov_arr")==0 || + s.substr(0,s.find_first_of(" ")).compare("ptr")==0 || s.substr(0,s.find_first_of(" ")).compare("ptr$")==0 || + s.substr(0,s.find_first_of(" ")).compare("redim1")==0 || s.substr(0,s.find_first_of(" ")).compare("redim1$")==0 || + s.substr(0,s.find_first_of(" ")).compare("for_offset_arr2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_n1")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr_s1")==0 || s.substr(0,s.find_first_of(" ")).compare("uref_ptr")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr_init1")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t")==0) + { + current_address[current_segment] += 17; //1 byte for instruction and 8 bytes for each argument + } + else if(s.substr(0,s.find_first_of(" ")).compare("push")==0 ) + { + n_stack_count++; + if( (n_stack_count+1) > max_n_stack_count) + max_n_stack_count = n_stack_count+1; + current_address[current_segment] += 9; + } + else if(s.substr(0,s.find_first_of(" ")).compare("push$")==0 ) + { + s_stack_count++; + if( (s_stack_count+1) > max_s_stack_count) + max_s_stack_count = s_stack_count+1; + current_address[current_segment] += 9; + } + else if(s.substr(0,s.find_first_of(" ")).compare("push_t")==0 ) + { + u_stack_count++; + if( (u_stack_count+1) > max_u_stack_count) + max_u_stack_count = u_stack_count+1; + current_address[current_segment] += 9; + } + else if(s.substr(0,s.find_first_of(" ")).compare("pop")==0) + { + n_stack_count--; + current_address[current_segment] += 9; + } + else if(s.substr(0,s.find_first_of(" ")).compare("pop$")==0) + { + s_stack_count--; + current_address[current_segment] += 9; + } + else if(s.substr(0,s.find_first_of(" ")).compare("pop_t")==0) + { + u_stack_count--; + current_address[current_segment] += 9; + } + else if(s.substr(0,s.find_first_of(" ")).compare("jmp")==0 || s.substr(0,s.find_first_of(" ")).compare("je")==0 || + s.substr(0,s.find_first_of(" ")).compare("jne")==0 || s.substr(0,s.find_first_of(" ")).compare("jg")==0 || + s.substr(0,s.find_first_of(" ")).compare("jge")==0 || s.substr(0,s.find_first_of(" ")).compare("jl")==0 || + s.substr(0,s.find_first_of(" ")).compare("jle")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_num")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_str")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_get")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_get$")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_set")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_set$")==0 || + s.substr(0,s.find_first_of(" ")).compare("delete")==0 || s.substr(0,s.find_first_of(" ")).compare("delete$")==0 || + s.substr(0,s.find_first_of(" ")).compare("get_stack_size")==0 || s.substr(0,s.find_first_of(" ")).compare("get_stack_size$")==0 || + s.substr(0,s.find_first_of(" ")).compare("wend")==0 || s.substr(0,s.find_first_of(" ")).compare("loop")==0 || + s.substr(0,s.find_first_of(" ")).compare("gosub")==0 || s.substr(0,s.find_first_of(" ")).compare("print")==0 || + s.substr(0,s.find_first_of(" ")).compare("print$")==0 || s.substr(0,s.find_first_of(" ")).compare("func")==0 || + s.substr(0,s.find_first_of(" ")).compare("not")==0 || s.substr(0,s.find_first_of(" ")).compare("next")==0 || + s.substr(0,s.find_first_of(" ")).compare("pop_ptr")==0 || s.substr(0,s.find_first_of(" ")).compare("preset")==0 || + s.substr(0,s.find_first_of(" ")).compare("preset$")==0 || s.substr(0,s.find_first_of(" ")).compare("for_offset_arr1")==0 || + s.substr(0,s.find_first_of(" ")).compare("end_x")==0 || s.substr(0,s.find_first_of(" ")).compare("lval")==0 || + s.substr(0,s.find_first_of(" ")).compare("lval$")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_n")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr_s")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_get")==0 || + s.substr(0,s.find_first_of(" ")).compare("delete_t")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_init")==0) + { + current_address[current_segment] += 9; //1 byte for instruction and 8 bytes a single argument + } + else if(s.substr(0,s.find_first_of(" ")).compare("obj_num2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_str2")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr2")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_type1")==0 || + s.substr(0,s.find_first_of(" ")).compare("dim_num2")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_str2")==0 || + s.substr(0,s.find_first_of(" ")).compare("redim2")==0 || s.substr(0,s.find_first_of(" ")).compare("redim2$")==0 || + s.substr(0,s.find_first_of(" ")).compare("for_offset_arr3")==0 || s.substr(0,s.find_first_of(" ")).compare("dbg")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr_n2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_s2")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr_init2")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t1")==0) + { + current_address[current_segment] += 25; //1 byte for instruction and 8 bytes for 3 arguments + } + else if(s.substr(0,s.find_first_of(" ")).compare("dim_type2")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_num3")==0 || + s.substr(0,s.find_first_of(" ")).compare("dim_str3")==0 || s.substr(0,s.find_first_of(" ")).compare("for")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_num3")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_str3")==0 || + s.substr(0,s.find_first_of(" ")).compare("redim3")==0 || s.substr(0,s.find_first_of(" ")).compare("redim3$")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr_n3")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_s3")==0 || + s.substr(0,s.find_first_of(" ")).compare("obj_usr3")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_init3")==0 || + s.substr(0,s.find_first_of(" ")).compare("preset_t2")==0) + { + current_address[current_segment] += 33; //1 byte for instruction and 8 bytes for 4 arguments + } + else if(s.substr(0,s.find_first_of(" ")).compare("dim_type3")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t3")==0) + { + current_address[current_segment] += 41; //1 byte for instruction and 8 bytes for 5 arguments + } + else if(s.substr(0,s.find_first_of(" ")).compare("end")==0 || s.substr(0,s.find_first_of(" ")).compare("clear_obj")==0 || + s.substr(0,s.find_first_of(" ")).compare("push_empty$")==0 || s.substr(0,s.find_first_of(" ")).compare("clear_stack")==0 || + s.substr(0,s.find_first_of(" ")).compare("clear_stack$")==0 || s.substr(0,s.find_first_of(" ")).compare("do")==0 || + s.substr(0,s.find_first_of(" ")).compare("pop_loop_stack")==0 || s.substr(0,s.find_first_of(" ")).compare("return")==0 || + s.substr(0,s.find_first_of(" ")).compare("println")==0 || s.substr(0,s.find_first_of(" ")).compare("for_offset_0")==0 || + s.substr(0,s.find_first_of(" ")).compare("push_t_null")==0) + { + current_address[current_segment] += 1; //1 byte for instruction and no arguments + } + else if(s.substr(0,s.find_first_of(" ")).compare("dim_tfield")==0) + { + current_address[current_segment] += 57; + } + else + { + cout << "Unknown Instruction" << endl; + } + } + + void clear() + { + vm_code.clear(); + } + + uint64_t size() + { + return vm_code.size(); + } +}; + +rc_vm_asm vm_asm; + +//vector vm_asm; //the generated opcodes for the current set of +//vector vm_data_asm; + +vector data_segment; +vector resolveID_id_reg; +vector resolveID_id_type; +vector resolveID_id_ut_index; +vector resolveID_id_vec_pos; + +int getResolveReg(string arg) +{ + for(int i = 0; i < resolveID_id_reg.size(); i++) + { + //cout << "compare (" << arg << " to " << resolveID_id_reg[i] << endl; + if(resolveID_id_reg[i].compare(arg)==0) + return i; + } + return -1; +} + +int rid_count = 0; + +#endif // RC_GLOBAL_INCLUDED diff --git a/rcbasic_build/rc_utility.h b/rcbasic_build/rc_utility.h new file mode 100644 index 0000000..706a78f --- /dev/null +++ b/rcbasic_build/rc_utility.h @@ -0,0 +1,72 @@ +#ifndef RC_UTILITY_H_INCLUDED +#define RC_UTILITY_H_INCLUDED +#include +#include +#include + +using namespace std; + +string rc_intToString(int a) +{ + stringstream ss; + ss << a; + string str = ss.str(); + ss.clear(); + return str; +} + +string rc_uint64ToString(uint64_t a) +{ + stringstream ss; + ss << a; + string str = ss.str(); + ss.clear(); + return str; +} + +int rc_stringToInt(string a) +{ + stringstream ss; + ss << a; + int i = 0; + ss >> i; + ss.clear(); + return i; +} + +string StringToUpper(string strToConvert) +{//change each element of the string to upper case + for(unsigned int i=0;i= s.length()) + return ""; + if( (start_pos+num_char) >= s.length()) + return s.substr(start_pos); + return s.substr(start_pos, num_char); +} + +bool is_file_exist(const char *fileName) +{ + std::ifstream infile(fileName); + return infile.good(); +} + +#endif // RC_UTILITY_H_INCLUDED diff --git a/rcbasic_build/rc_vm_asm.h b/rcbasic_build/rc_vm_asm.h new file mode 100644 index 0000000..5b28db8 --- /dev/null +++ b/rcbasic_build/rc_vm_asm.h @@ -0,0 +1,1480 @@ +#ifndef RC_VM_ASM_H_INCLUDED +#define RC_VM_ASM_H_INCLUDED + +#define RC_CLEAN_AFTER_BUILD true +#define RC_NO_CLEAN_AFTER_BUILD false + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#define LESS_FLAG 0 +#define LESS_EQUAL_FLAG 1 +#define GREATER_FLAG 2 +#define GREATER_EQUAL_FLAG 3 +#define EQUAL_FLAG 4 +#define NOT_EQUAL_FLAG 5 + +#define CODE_SEGMENT 0 +#define DATA_SEGMENT 1 + +namespace rc_cbc_assembler +{ + + uint64_t numID_count = 0; + uint64_t strID_count = 0; + uint64_t usrID_count = 0; + + uint64_t vm_n_count = 0; + uint64_t vm_s_count = 0; + uint64_t vm_u_count = 0; + + uint64_t n_stack_size = 0; + uint64_t s_stack_size = 0; + uint64_t u_stack_size = 0; + uint64_t loop_stack_size = 0; + + uint64_t str_data_size = 0; + + struct rc_label + { + string label_name; + uint64_t label_address; + int label_segment; + }; + + vector label; + + vector rc_code_segment; + vector rc_data_segment; + int current_segment = 0; + + string rc_intToString(int a) + { + stringstream ss; + ss << a; + string str = ss.str(); + ss.clear(); + return str; + } + + int rc_stringToInt(string a) + { + stringstream ss; + ss << a; + int i = 0; + ss >> i; + ss.clear(); + return i; + } + + double rc_stringToDouble(string a) + { + double d = atof(a.c_str()); + return d; + } + + bool isDigit(char c) + { + return (c >= '0' && c <= '9'); + } + + int rc_find_digit(string line) + { + for(int i = 0; i < line.length(); i++) + { + if(isDigit(line[i])) + return i; + } + return -1; + } + + bool loadData(string datafile, string str_datafile) + { + + fstream f(str_datafile.c_str(), fstream::in); + if(!f.is_open()) + return false; + + char c; + while(true) + { + f.get(c); + + if(f.eof()) + break; + rc_data_segment.push_back(c); + } + f.close(); + + str_data_size = rc_data_segment.size(); + f.open(datafile.c_str(), fstream::in); + if(!f.is_open()) + return false; + //n_count + //s_count + //n_stack_count + //s_stack_count + //loop_stack_count + //numID_count + //strID_count + //label_count + //labels + + string line = ""; + + getline(f, line); + vm_n_count = rc_stringToInt(line); + + getline(f, line); + vm_s_count = rc_stringToInt(line); + + getline(f, line); + vm_u_count = rc_stringToInt(line); + + getline(f, line); + n_stack_size = rc_stringToInt(line); + + getline(f, line); + s_stack_size = rc_stringToInt(line); + + getline(f, line); + u_stack_size = rc_stringToInt(line); + + getline(f, line); + loop_stack_size = rc_stringToInt(line); + + getline(f, line); + numID_count = rc_stringToInt(line); + + getline(f, line); + strID_count = rc_stringToInt(line); + + getline(f, line); + usrID_count = rc_stringToInt(line); + + getline(f, line); + int num_labels = rc_stringToInt(line); + + rc_label lbl; + //cout << "num labels equals " << num_labels << endl; + + for(int i = 0; i < num_labels; i++) + { + getline(f, line); + lbl.label_name = line.substr(0, line.find_first_of(" ")); + + line = line.substr(line.find_first_of(" ")); + line = line.substr(line.find_first_not_of(" ")); + + lbl.label_address = rc_stringToInt(line.substr(0, line.find_first_of(" "))); + + line = line.substr(line.find_first_of(" ")); + lbl.label_segment = rc_stringToInt(line.substr(line.find_first_not_of(" "))); + + if(lbl.label_segment == DATA_SEGMENT) + { + //cout << lbl.label_name << " is in data: " << lbl.label_address << endl; + lbl.label_address += str_data_size; + } + else + { + //cout << lbl.label_name << " segment = " << lbl.label_segment << endl; + } + label.push_back(lbl); + } + + f.close(); + + return true; + } + + union u_double + { + double f; + unsigned char data[sizeof(double)]; + }; + + union ru_int + { + uint64_t i; + unsigned char data[sizeof(uint64_t)]; + }; + + + void writeSegment(unsigned char c) + { + switch(current_segment) + { + case CODE_SEGMENT: + rc_code_segment.push_back(c); + break; + case DATA_SEGMENT: + rc_data_segment.push_back(c); + break; + } + } + + string line_arg[10]; + int line_arg_count = 0; + + bool parseLine(string line) + { + line += " "; //add a space so that it reads the last argument on the line + line_arg_count = 0; + for(int i = 0; i < 10; i++) + line_arg[i] = ""; + for(int i = 0; i < line.length(); i++) + { + if(line.substr(i,1).compare(" ")==0) + { + //cout << "line_arg[" << line_arg_count << "] = " << line_arg[line_arg_count] << endl; + line_arg_count++; + for(; i < line.length(); i++) + { + if(line.substr(i,1).compare(" ")!=0) + break; + } + i--; + } + else + { + line_arg[line_arg_count] += line.substr(i,1); + } + } + return true; + } + + bool LABEL_NOT_FOUND = false; + + uint64_t lookUpAddress(string lbl_name) + { + LABEL_NOT_FOUND = false; + for(int i = 0; i < label.size(); i++) + { + if(label[i].label_name.compare(lbl_name)==0) + return label[i].label_address; + } + LABEL_NOT_FOUND = true; + return -1; + } + + bool genByteCode(string asm_file) + { + fstream f(asm_file.c_str(), fstream::in); + + string line = ""; + + u_double rc_dbl; + ru_int rc_int; + + while(true) + { + //cout << "start" << endl; + getline(f, line); + + if(f.eof()) + { + return true; + } + + //cout << "balls" << endl; + + parseLine(line); + //cout << "line = " << line << endl; + + if(line_arg[0].compare(".code")==0) + { + //cout << "switching to code" << endl; + current_segment = CODE_SEGMENT; + } + else if(line_arg[0].compare(".data")==0) + { + //cout << "switching to data" << endl; + current_segment = DATA_SEGMENT; + } + else if(line_arg[0].compare("label")==0) + { + continue; + } + else if(line_arg[0].compare("end")==0) + { + writeSegment(0); + } + else if(line_arg[0].compare("dbg")==0) + { + writeSegment(1); + } + else if(line_arg[0].compare("mov")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(32); + } + else if(arg1_type.compare("n")==0 && (isDigit(arg2_type[0]) || arg2_type[0]=='-')) + { + writeSegment(33); + } + else if(arg1_type.compare("n")==0 && arg2_type.compare("!")==0) + { + writeSegment(34); + } + else if(arg1_type.compare("!")==0 && arg2_type.compare("n")==0) + { + writeSegment(35); + } + else if(arg1_type.compare("n")==0 && arg2_type.compare("%")==0) + { + writeSegment(133); + } + } + else if(line_arg[0].compare("mov$")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("s")==0 && arg2_type.compare("s")==0) + { + writeSegment(36); + } + else if(arg1_type.compare("s")==0 && arg2_type.compare("@")==0) + { + writeSegment(37); + } + else if(arg1_type.compare("s")==0 && arg2_type.compare("!")==0) + { + writeSegment(38); + } + else if(arg1_type.compare("!")==0 && arg2_type.compare("s")==0) + { + writeSegment(39); + } + } + else if(line_arg[0].compare("mov_r")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(40); + } + else + cout << "Error mov_r" << endl; + } + else if(line_arg[0].compare("mov_r$")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("s")==0 && arg2_type.compare("s")==0) + { + writeSegment(41); + } + else + cout << "Error mov_r" << endl; + } + else if(line_arg[0].compare("mov_type")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("!")==0 && arg2_type.compare("u")==0) + { + writeSegment(168); + } + else if(arg1_type.compare("u")==0 && arg2_type.compare("u")==0) + { + writeSegment(42); + } + } + else if(line_arg[0].compare("add$")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("s")==0 && arg2_type.compare("s")==0) + { + writeSegment(43); + } + else + cout << "Error add$" << endl; + } + else if(line_arg[0].compare("add")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(44); + } + else + cout << "Error add" << endl; + } + else if(line_arg[0].compare("sub")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(45); + } + else + cout << "Error sub" << endl; + } + else if(line_arg[0].compare("mul")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(46); + } + else + cout << "Error mul" << endl; + } + else if(line_arg[0].compare("div")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(47); + } + else + cout << "Error div" << endl; + } + else if(line_arg[0].compare("pow")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(48); + } + else + cout << "Error pow" << endl; + } + else if(line_arg[0].compare("mod")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(49); + } + else + cout << "Error mod" << endl; + } + else if(line_arg[0].compare("shl")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(50); + } + else + cout << "Error shl" << endl; + } + else if(line_arg[0].compare("shr")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(51); + } + else + cout << "Error shr" << endl; + } + else if(line_arg[0].compare("and")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(52); + } + else + cout << "Error and" << endl; + } + else if(line_arg[0].compare("or")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(53); + } + else + cout << "Error or" << endl; + } + else if(line_arg[0].compare("xor")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(54); + } + else + cout << "Error xor" << endl; + } + else if(line_arg[0].compare("not")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(55); + } + else + cout << "Error not" << endl; + } + else if(line_arg[0].compare("cmp")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(56); + } + else if(arg1_type.compare("n")==0 && (isDigit(arg2_type[0]) || arg2_type[0] == '-')) + { + writeSegment(134); + } + else + cout << "Error cmp: " << line << endl; + } + else if(line_arg[0].compare("cmp$")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("s")==0 && arg2_type.compare("s")==0) + { + writeSegment(57); + } + else + cout << "Error cmp$" << endl; + } + else if(line_arg[0].compare("cmp_u")==0) + { + string arg1_type = line_arg[1].substr(0,1); + string arg2_type = line_arg[2].substr(0,1); + + if(arg1_type.compare("n")==0 && arg2_type.compare("n")==0) + { + writeSegment(58); + } + else + cout << "Error cmp_u" << endl; + } + else if(line_arg[0].compare("jmp")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(59); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(60); + } + else + cout << "Error jmp" << endl; + } + else if(line_arg[0].compare("je")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(61); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(62); + } + else + cout << "Error je" << endl; + } + else if(line_arg[0].compare("jne")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(63); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(64); + } + else + cout << "Error jne" << endl; + } + else if(line_arg[0].compare("jg")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(65); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(66); + } + else + cout << "Error jg" << endl; + } + else if(line_arg[0].compare("jge")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(67); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(68); + } + else + cout << "Error jge" << endl; + } + else if(line_arg[0].compare("jl")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(69); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(70); + } + else + cout << "Error jl" << endl; + } + else if(line_arg[0].compare("jle")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(71); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(72); + } + else + cout << "Error jle" << endl; + } + else if(line_arg[0].compare("obj_num")==0) + { + writeSegment(73); + } + else if(line_arg[0].compare("obj_num1")==0) + { + writeSegment(74); + } + else if(line_arg[0].compare("obj_num2")==0) + { + writeSegment(75); + } + else if(line_arg[0].compare("obj_num3")==0) + { + writeSegment(76); + } + else if(line_arg[0].compare("obj_str")==0) + { + writeSegment(77); + } + else if(line_arg[0].compare("obj_str1")==0) + { + writeSegment(78); + } + else if(line_arg[0].compare("obj_str2")==0) + { + writeSegment(79); + } + else if(line_arg[0].compare("obj_str3")==0) + { + writeSegment(80); + } + else if(line_arg[0].compare("obj_usr")==0) + { + writeSegment(81); + } + else if(line_arg[0].compare("obj_usr1")==0) + { + writeSegment(82); + } + else if(line_arg[0].compare("obj_usr2")==0) + { + writeSegment(83); + } + else if(line_arg[0].compare("obj_usr3")==0) + { + writeSegment(84); + } + else if(line_arg[0].compare("obj_get")==0) + { + writeSegment(85); + } + else if(line_arg[0].compare("obj_get$")==0) + { + writeSegment(86); + } + else if(line_arg[0].compare("obj_set")==0) + { + writeSegment(87); + } + else if(line_arg[0].compare("obj_set$")==0) + { + writeSegment(88); + } + else if(line_arg[0].compare("clear_obj")==0) + { + writeSegment(89); + } + else if(line_arg[0].compare("dim_type")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("u")==0) + writeSegment(175); + else if(arg_type.compare("!")==0) + writeSegment(90); + } + else if(line_arg[0].compare("dim_type1")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("u")==0) + writeSegment(176); + else if(arg_type.compare("!")==0) + writeSegment(91); + } + else if(line_arg[0].compare("dim_type2")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("u")==0) + writeSegment(177); + else if(arg_type.compare("!")==0) + writeSegment(92); + } + else if(line_arg[0].compare("dim_type3")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("u")==0) + writeSegment(178); + else if(arg_type.compare("!")==0) + writeSegment(93); + } + else if(line_arg[0].compare("dim_num1")==0) + { + writeSegment(94); + } + else if(line_arg[0].compare("dim_num2")==0) + { + writeSegment(95); + } + else if(line_arg[0].compare("dim_num3")==0) + { + writeSegment(96); + } + else if(line_arg[0].compare("dim_str1")==0) + { + writeSegment(97); + } + else if(line_arg[0].compare("dim_str2")==0) + { + writeSegment(98); + } + else if(line_arg[0].compare("dim_str3")==0) + { + writeSegment(99); + } + else if(line_arg[0].compare("delete")==0) + { + writeSegment(100); + } + else if(line_arg[0].compare("delete$")==0) + { + writeSegment(101); + } + else if(line_arg[0].compare("push")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("n")==0) + writeSegment(102); + else if(arg_type.compare("!")==0) + writeSegment(103); + else if(isDigit(arg_type[0]) || arg_type[0]=='-') + writeSegment(131); + } + else if(line_arg[0].compare("push$")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("s")==0) + writeSegment(104); + else if(arg_type.compare("!")==0) + writeSegment(105); + } + else if(line_arg[0].compare("push_empty$")==0) + { + writeSegment(106); + } + else if(line_arg[0].compare("pop")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("n")==0) + writeSegment(107); + else if(arg_type.compare("!")==0) + writeSegment(108); + } + else if(line_arg[0].compare("pop$")==0) + { + string arg_type = line_arg[1].substr(0,1); + if(arg_type.compare("s")==0) + writeSegment(109); + else if(arg_type.compare("!")==0) + writeSegment(110); + } + else if(line_arg[0].compare("get_stack_size")==0) + { + writeSegment(111); + } + else if(line_arg[0].compare("get_stack_size$")==0) + { + writeSegment(112); + } + else if(line_arg[0].compare("clear_stack")==0) + { + writeSegment(113); + } + else if(line_arg[0].compare("clear_stack$")==0) + { + writeSegment(114); + } + else if(line_arg[0].compare("while")==0) + { + writeSegment(115); + } + else if(line_arg[0].compare("wend")==0) + { + writeSegment(116); + } + else if(line_arg[0].compare("for")==0) + { + writeSegment(117); + } + else if(line_arg[0].compare("next")==0) + { + writeSegment(118); + } + else if(line_arg[0].compare("do")==0) + { + writeSegment(119); + } + else if(line_arg[0].compare("loop")==0) + { + writeSegment(120); + } + else if(line_arg[0].compare("loop_while")==0) + { + writeSegment(121); + } + else if(line_arg[0].compare("loop_until")==0) + { + writeSegment(122); + } + else if(line_arg[0].compare("pop_loop_stack")==0) + { + writeSegment(123); + } + else if(line_arg[0].compare("gosub")==0) + { + writeSegment(124); + } + else if(line_arg[0].compare("return")==0) + { + writeSegment(125); + } + else if(line_arg[0].compare("ptr")==0) + { + writeSegment(126); + } + else if(line_arg[0].compare("ptr$")==0) + { + writeSegment(127); + } + else if(line_arg[0].compare("print")==0) + { + writeSegment(128); + } + else if(line_arg[0].compare("print$")==0) + { + writeSegment(129); + } + else if(line_arg[0].compare("func")==0) + { + writeSegment(130); + } + else if(line_arg[0].compare("println")==0) + { + writeSegment(132); + } + else if(line_arg[0].compare("mov_arr")==0) + { + writeSegment(135); + } + else if(line_arg[0].compare("mov_arr$")==0) + { + writeSegment(136); + } + else if(line_arg[0].compare("pop_ptr")==0) + { + writeSegment(137); + } + else if(line_arg[0].compare("preset")==0) + { + writeSegment(138); + } + else if(line_arg[0].compare("preset$")==0) + { + writeSegment(139); + } + else if(line_arg[0].compare("redim1")==0) + { + writeSegment(140); + } + else if(line_arg[0].compare("redim2")==0) + { + writeSegment(141); + } + else if(line_arg[0].compare("redim3")==0) + { + writeSegment(142); + } + else if(line_arg[0].compare("redim1$")==0) + { + writeSegment(143); + } + else if(line_arg[0].compare("redim2$")==0) + { + writeSegment(144); + } + else if(line_arg[0].compare("redim3$")==0) + { + writeSegment(145); + } + else if(line_arg[0].compare("for_offset_arr1")==0) + { + writeSegment(146); + } + else if(line_arg[0].compare("for_offset_arr2")==0) + { + writeSegment(147); + } + else if(line_arg[0].compare("for_offset_arr3")==0) + { + writeSegment(148); + } + else if(line_arg[0].compare("for_offset_0")==0) + { + writeSegment(149); + } + else if(line_arg[0].compare("end_x")==0) + { + writeSegment(150); + } + else if(line_arg[0].compare("lval")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(151); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(152); + } + else if(arg1_type.compare("@")==0) + { + writeSegment(153); + } + else + cout << "Error lval" << endl; + } + else if(line_arg[0].compare("lval$")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("s")==0) + { + writeSegment(154); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(155); + } + else + cout << "Error lval$" << endl; + } + else if(line_arg[0].compare("obj_usr_n")==0) + { + writeSegment(156); + } + else if(line_arg[0].compare("obj_usr_n1")==0) + { + writeSegment(157); + } + else if(line_arg[0].compare("obj_usr_n2")==0) + { + writeSegment(158); + } + else if(line_arg[0].compare("obj_usr_n3")==0) + { + writeSegment(159); + } + else if(line_arg[0].compare("obj_usr_s")==0) + { + writeSegment(160); + } + else if(line_arg[0].compare("obj_usr_s1")==0) + { + writeSegment(161); + } + else if(line_arg[0].compare("obj_usr_s2")==0) + { + writeSegment(162); + } + else if(line_arg[0].compare("obj_usr_s3")==0) + { + writeSegment(163); + } + else if(line_arg[0].compare("obj_usr_get")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("n")==0) + { + writeSegment(164); + } + else if(arg1_type.compare("s")==0) + { + writeSegment(165); + } + else if(arg1_type.compare("u")==0) + { + writeSegment(166); + } + } + else if(line_arg[0].compare("uref_ptr")==0) + { + writeSegment(167); + } + else if(line_arg[0].compare("push_t")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("u")==0) + { + writeSegment(169); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(170); + } + } + else if(line_arg[0].compare("pop_t")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("u")==0) + { + writeSegment(171); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(172); + } + } + else if(line_arg[0].compare("push_t_null")==0) + { + writeSegment(173); + } + else if(line_arg[0].compare("delete_t")==0) + { + writeSegment(174); + } + else if(line_arg[0].compare("dim_tfield")==0) + { + writeSegment(179); + } + else if(line_arg[0].compare("obj_usr_init")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("u")==0) + { + writeSegment(184); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(180); + } + } + else if(line_arg[0].compare("obj_usr_init1")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("u")==0) + { + writeSegment(185); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(181); + } + } + else if(line_arg[0].compare("obj_usr_init2")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("u")==0) + { + writeSegment(186); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(182); + } + } + else if(line_arg[0].compare("obj_usr_init3")==0) + { + string arg1_type = line_arg[1].substr(0,1); + + if(arg1_type.compare("u")==0) + { + writeSegment(187); + } + else if(arg1_type.compare("!")==0) + { + writeSegment(183); + } + } + else if(line_arg[0].compare("preset_t")==0) + { + writeSegment(188); + } + else if(line_arg[0].compare("preset_t1")==0) + { + writeSegment(189); + } + else if(line_arg[0].compare("preset_t2")==0) + { + writeSegment(190); + } + else if(line_arg[0].compare("preset_t3")==0) + { + writeSegment(191); + } + else + { + cout << "unrecognized cmd: " << line_arg[0] << endl; + return false; + } + + + + string arg_type = ""; + //cout << "line arg count = " << line_arg_count << endl << endl; + + for(int i = 1; i < line_arg_count; i++) + { + if(isDigit(line_arg[i][0]) || line_arg[i][0]=='-') + { + rc_dbl.f = rc_stringToDouble(line_arg[i]); + //cout << "dbl_f = " << rc_dbl.f << endl; + for(int n = 0; n < sizeof(double); n++) + writeSegment(rc_dbl.data[n]); + } + else if(line_arg[i].substr(0,1).compare("%")==0) + { + //compare flags + string cmp_flag = line_arg[i].substr(1)+" "; + cmp_flag = cmp_flag.substr(0, cmp_flag.find_first_of(" ")); + if(cmp_flag.compare("LESS_FLAG")==0) + { + rc_int.i = LESS_FLAG; + } + else if(cmp_flag.compare("LESS_EQUAL_FLAG")==0) + { + rc_int.i = LESS_EQUAL_FLAG; + } + else if(cmp_flag.compare("GREATER_FLAG")==0) + { + rc_int.i = GREATER_FLAG; + } + else if(cmp_flag.compare("GREATER_EQUAL_FLAG")==0) + { + rc_int.i = GREATER_EQUAL_FLAG; + } + else if(cmp_flag.compare("EQUAL_FLAG")==0) + { + rc_int.i = EQUAL_FLAG; + } + else if(cmp_flag.compare("NOT_EQUAL_FLAG")==0) + { + rc_int.i = NOT_EQUAL_FLAG; + } + else + { + cout << "invalid flag" << endl; + return false; + } + + for(int n = 0; n < sizeof(uint64_t); n++) + writeSegment(rc_int.data[n]); + } + else if(line_arg[i].substr(0,1).compare("@")==0) + { + rc_int.i = lookUpAddress(line_arg[i].substr(1)); + if(LABEL_NOT_FOUND) + { + if(isDigit(line_arg[i][1])) + { + rc_int.i = rc_stringToInt(line_arg[i].substr(1)); + } + else + { + cout << "something is really wrong" << endl; + return false; + } + } + for(int n = 0; n < sizeof(uint64_t); n++) + writeSegment(rc_int.data[n]); + } + else + { + int p = rc_find_digit(line_arg[i]); + rc_int.i = rc_stringToInt(line_arg[i].substr(p)); + if(rc_int.i < 0) + { + cout << "something is wrong" << endl; + return false; + } + for(int n = 0; n < sizeof(uint64_t); n++) + writeSegment(rc_int.data[n]); + } + } + } + return true; + } + + fstream output_file; + + void rc_write(ru_int rc_int) + { + for(int i = 0; i < sizeof(uint64_t); i++) + output_file.put(rc_int.data[i]); + } + + bool compileCBC(string file_name) + { + char header[] = {'R','C','4','0','A'}; + + ru_int rc_int; + u_double rc_dbl; + + output_file.open(file_name.c_str(), fstream::out | fstream::binary); + + if(!output_file.is_open()) + return false; + + output_file.write(header, 5); + + //------type header here------------ + rc_int.i = utype.size(); + rc_write(rc_int); + + //loop through each type + for(int i = 0; i < utype.size(); i++) + { + //num fields + rc_int.i = utype[i].num_members; + rc_write(rc_int); + + //loop through each member + for(int member = 0; member < utype[i].num_members; member++) + { + // member type + switch(utype[i].member_type[member]) + { + case ID_TYPE_USER_NUM: + case ID_TYPE_USER_NUM_ARRAY: + rc_int.i = 0; + break; + case ID_TYPE_USER_STR: + case ID_TYPE_USER_STR_ARRAY: + rc_int.i = 1; + break; + case ID_TYPE_USER: + rc_int.i = 2; + break; + //default: + // cout << "type = " << utype[i].member_type[member] << endl; + } + rc_write(rc_int); + + rc_int.i = utype[i].member_utype_index[member]; + rc_write(rc_int); + + rc_int.i = utype[i].member_dim_count[member]; + rc_write(rc_int); + } + } + //-------end type header------------- + + rc_int.i = vm_n_count; + rc_write(rc_int); + + rc_int.i = vm_s_count; + rc_write(rc_int); + + rc_int.i = vm_u_count; + rc_write(rc_int); + + rc_int.i = n_stack_size; + rc_write(rc_int); + + rc_int.i = s_stack_size; + rc_write(rc_int); + + rc_int.i = u_stack_size; + rc_write(rc_int); + + rc_int.i = loop_stack_size; + rc_write(rc_int); + + rc_int.i = numID_count; + rc_write(rc_int); + + rc_int.i = strID_count; + rc_write(rc_int); + + rc_int.i = usrID_count; + rc_write(rc_int); + + rc_int.i = rc_code_segment.size(); + rc_write(rc_int); + + rc_int.i = rc_data_segment.size(); + rc_write(rc_int); + + //cout << "data is " << rc_data_segment.size() << endl << endl; + + for(int i = 0; i < rc_code_segment.size(); i++) + { + output_file.put(rc_code_segment[i]); + } + + for(int i = 0; i < rc_data_segment.size(); i++) + { + output_file.put(rc_data_segment[i]); + } + + output_file.close(); + + return true; + } + + bool is_file_exist(const char *fileName) + { + std::ifstream infile(fileName); + return infile.good(); + } + + void rc_clean() + { + if(is_file_exist("main.rc_data")) + remove("main.rc_data"); + if(is_file_exist("main_str_data.sdata")) + remove("main_str_data.sdata"); + if(is_file_exist("main.rc_asm")) + remove("main.rc_asm"); + } + + int rc_assemble(string cbc_file, bool clean_after_build=RC_CLEAN_AFTER_BUILD) + { + + if(is_file_exist(cbc_file.c_str())) + remove(cbc_file.c_str()); + + if(!loadData("main.rc_data", "main_str_data.sdata")) + { + cout << "Error loading compiler data" << endl; + if(clean_after_build) rc_clean(); + return 0; + } + if(!genByteCode("main.rc_asm")) + { + cout << "Error generating bytecode" << endl; + if(clean_after_build) rc_clean(); + return 0; + } + if(!compileCBC(cbc_file)) + { + cout << "Error generating CBC file" << endl; + if(clean_after_build) rc_clean(); + return 0; + } + cout << "RCBasic Binary Program compiled" << endl; + + //debug + //fstream f("code.dbg", fstream::out | fstream::binary); + //for(int i = 0; i < rc_code_segment.size(); i++) + // f.put(rc_code_segment[i]); + //f.close(); + //f.open("data.dbg", fstream::out | fstream::binary); + + //for(int i = 0; i < rc_data_segment.size(); i++) + // f.put(rc_data_segment[i]); + + //f.close(); + //end debug + if(clean_after_build) rc_clean(); + return 0; + } +} + + +#endif // RC_VM_ASM_H_INCLUDED diff --git a/rcbasic_build/tokenizer.h b/rcbasic_build/tokenizer.h new file mode 100644 index 0000000..e91f8de --- /dev/null +++ b/rcbasic_build/tokenizer.h @@ -0,0 +1,1052 @@ + +#ifndef TOKENIZER_H_INCLUDED +#define TOKENIZER_H_INCLUDED + +#include +#include +#include +#include +#include +#include "rc_utility.h" +#include "rc_debug.h" +#include "keywords.h" +#include "constants.h" + +using namespace std; + +vector token; //stores tokens for the current source line +vector tmp_token; //stores tokens for the current source line +string rc_keywordToken(string sline); +bool isKeyWord(string key); +bool tokens(const std::string &data); //reads current source line and fills token vector +int inc(string::size_type &, int); //returns the current position being read on the current source line +int iswhite(int); //returns whether the current character is a whitespace +bool isLetter(char c); //returns whether or not the current character is a letter +bool isDigit(char ch); //returns whether or not the current character is a digit +bool isOperatorToken(int token_index); //returns whether or not the token at the given index is an operator +void output_tokens(); //outputs the last set of tokens generated +void clearTokens(); +bool multi_line_comment=false; + +bool isOperatorToken(int token_index) +{ + int x = token_index; + + if(x < 0) + return false; + + if(tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("
")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0 || + tmp_token[x].compare("")==0 || tmp_token[x].compare("")==0) + { + return true; + } + + return false; +} + +bool isOperatorToken2(int token_index) +{ + int x = token_index; + + if(x < 0) + return false; + + if(token[x].compare("")==0 || token[x].compare("")==0 || + token[x].compare("")==0 || token[x].compare("
")==0 || + token[x].compare("")==0 || token[x].compare("")==0 || + token[x].compare("")==0 || token[x].compare("")==0 || + token[x].compare("")==0 || token[x].compare("")==0 || + token[x].compare("")==0 || token[x].compare("")==0 || + token[x].compare("")==0 || token[x].compare("")==0 || + token[x].compare("")==0 || token[x].compare("")==0) + { + return true; + } + + return false; +} + +bool isSubDelimToken(int token_index) +{ + if(token_index < 0) + return false; + + if(tmp_token[token_index].compare("")==0 || + tmp_token[token_index].compare("")==0 || + tmp_token[token_index].compare("")==0 || + tmp_token[token_index].compare("")==0 || + tmp_token[token_index].compare("!")==0 || + tmp_token[token_index].compare("!")==0 || + tmp_token[token_index].compare("!")==0 || + tmp_token[token_index].compare("!")==0) + return true; + + string t = tmp_token[token_index].substr(1); + t = t.substr(0, t.find_first_of(">")); + if(isKeyWord(StringToUpper(t))) + return true; + + return false; +} + +bool tokens(const std::string &data) +{ + string::size_type x = 0; + bool esc_char = false; + + string arg_data = ""; + int arg_data_scope = 0; + + if(multi_line_comment) + { + x = data.find("'/"); + if(x == string::npos) + return true; + + multi_line_comment = false; + x += 2; + } + + while(x < data.length()) + { + char ch = data[x]; + + //s_data will hold a number or identifier + string s_data = ""; + string rc_builtin_constant = ""; + + while(isspace(ch)) + ch = data[inc(x, 1)]; + + switch(ch) + { + case ':': + inc(x, 1); + tmp_token.push_back("<:>"); + break; + case '.': + inc(x, 1); + tmp_token.push_back(""); + break; + case '+': + inc(x, 1); + tmp_token.push_back(""); + break; + case '-': + if(isOperatorToken(tmp_token.size()-1) || isSubDelimToken(tmp_token.size()-1) || tmp_token.size()==0) + { + ch = data[inc(x, 1)]; + if (isdigit(ch)) + { + s_data = "-"; + do + { + s_data.push_back(ch); + ch = data[inc(x, 1)]; + } while(isdigit(ch) || ch == '.'); + + tmp_token.push_back(s_data); + } + else if (isalpha(ch) || ch == '_') + { + //s_data = ""; + do + { + s_data.push_back(ch); + ch = data[inc(x, 1)]; + } while(isalnum(ch) || ch == '_'); + + if(ch=='(') + { + arg_data = ""; + arg_data_scope = 0; + do + { + arg_data.push_back(ch); + + if(ch=='(') + arg_data_scope++; + else if(ch==')') + arg_data_scope--; + + ch = data[inc(x, 1)]; + + } while(arg_data_scope > 0 && x < data.length()); + } + else if(ch=='[') + { + arg_data = ""; + arg_data_scope = 0; + do + { + arg_data.push_back(ch); + + if(ch=='[') + arg_data_scope++; + else if(ch==']') + arg_data_scope--; + + ch = data[inc(x, 1)]; + + } while(arg_data_scope > 0 && x < data.length()); + } + + if(isKeyWord(StringToUpper(s_data))) + { + //s_data = "<"+s_data+">"; + //keyword = s_data; + rc_setError("Invalid Syntax: Can't use Keyword " + s_data + " in this operation"); + return false; + } + else + { + s_data = ""+s_data; + + tmp_token.push_back(""); + tmp_token.push_back("-1"); + tmp_token.push_back(""); + tmp_token.push_back(s_data); + if(arg_data.compare("")!=0) + tokens(arg_data); + tmp_token.push_back(""); + } + } + else + { + rc_setError("Invalid Syntax: Missing a number or variable to negate"); + return false; + } + } + else + { + inc(x, 1); + tmp_token.push_back(""); + } + break; + case '*': + inc(x, 1); + tmp_token.push_back(""); + break; + case '/': + ch = data[x+1]; + if(ch == '\'') + { + //start multi-line comment + multi_line_comment = true; + size_t end_comment = data.substr(x+2).find("'/"); + if(end_comment == string::npos) + { + return true; + } + else + { + x += end_comment+4; + //cout << "data[" << x << "] = " << data[x] << endl; + multi_line_comment = false; + } + } + else + { + inc(x, 1); + tmp_token.push_back("
"); + } + break; + case '%': + inc(x, 1); + tmp_token.push_back(""); + break; + case '^': + inc(x, 1); + tmp_token.push_back(""); + break; + case '(': + inc(x, 1); + tmp_token.push_back(""); + break; + case ')': + inc(x, 1); + tmp_token.push_back(""); + break; + //case '.': + // inc(x, 1); + //token.push_back(""); + //break; + case ',': + inc(x, 1); + tmp_token.push_back(""); + break; + case ';': + inc(x, 1); + tmp_token.push_back(""); + break; + case '=': + inc(x, 1); + tmp_token.push_back(""); + break; + case '>': + ch = data[x+1]; + if(ch == '=') + { + inc(x, 2); + tmp_token.push_back(""); + } + else + { + inc(x, 1); + tmp_token.push_back(""); + } + break; + case '<': + ch = data[x+1]; + if (ch == '=') + { + inc(x, 2); + tmp_token.push_back(""); + } + else if (ch == '>') + { + inc(x, 2); + tmp_token.push_back(""); + } + else + { + inc(x, 1); + tmp_token.push_back(""); + } + break; + case '{': + inc(x, 1); + tmp_token.push_back(""); + break; + case '}': + inc(x, 1); + tmp_token.push_back(""); + break; + case '[': + inc(x, 1); + tmp_token.push_back(""); + break; + case ']': + inc(x, 1); + tmp_token.push_back(""); + break; + case '\'': + return true; + break; + case '\"': + s_data = ""; + ch = data[inc(x, 1)]; + while(ch != '\"' && ch != '\r' && ch != '\n' && ch != '\0') + { + if(ch == '\\') + { + esc_char = true; + } + if(esc_char) + { + ch = data[inc(x,1)]; + if(ch == '\\') + s_data.push_back('\\'); + else if(ch == '\"' || ch == 'q') + s_data.push_back('\"'); + else if(ch == '\'') + s_data.push_back('\''); + else if(ch == 'n') + s_data.push_back('\n'); + else if(ch == 'r') + s_data.push_back('\r'); + else if(ch == 't') + s_data.push_back('\t'); + else if(ch == '0') + s_data.push_back('\0'); + else if(ch == 'b') + s_data.push_back('\b'); + else if(ch == 'a') + s_data.push_back('\a'); + else if(ch == 'v') + s_data.push_back('\v'); + else if(ch == 'f') + s_data.push_back('\f'); + else + { + cout << "Invalid escape sequence in string expression: \\" << ch << endl; + return false; + } + esc_char = false; + ch = data[inc(x,1)]; + } + else + { + s_data.push_back(ch); + ch = data[inc(x, 1)]; + } + } + if (ch == '\"') + tmp_token.push_back(s_data); + else + { + rc_setError("String was not closed before end of line"); + return false; + } + inc(x, 1); + break; + default: + if (isdigit(ch)) + { + s_data = ""; + do + { + s_data.push_back(ch); + ch = data[inc(x, 1)]; + } while(isdigit(ch) || ch == '.'); + + tmp_token.push_back(s_data); + } + else if (isalpha(ch) || ch == '_') + { + //s_data = ""; + do + { + s_data.push_back(ch); + ch = data[inc(x, 1)]; + } while(isalnum(ch) || ch == '_' || ch == '$' );//|| ch == '.'); + + rc_builtin_constant = rc_keywordToken(StringToUpper(s_data)); + + string kw_s_data = StringToUpper(s_data); + if(isKeyWord(kw_s_data)) + { + s_data = "<"+StringToLower(kw_s_data.compare("SUB")==0 ? "subp" : s_data)+">"; + //keyword = s_data; + } + else if(rc_builtin_constant.compare("")!=0) + { + s_data = rc_builtin_constant; + rc_builtin_constant = ""; + } + else + { + s_data = ""+s_data; + } + + if(s_data.compare("")!=0) + tmp_token.push_back(s_data); + } + else if(ch == '~') + { + ch = data[inc(x,1)]; + do + { + s_data.push_back(ch); + ch = data[inc(x,1)]; + } while(isdigit(ch)); + tmp_token.push_back(s_data); + } + else if(x==data.length()) + { + break; + } + else + { + cout << "illegal character found" << endl; + return false; + } + break; + } + } + + return true; +} + +int inc(string::size_type &x, int by) +{ + return x = x + by; +} + +int iswhite(int c) +{ + return (c == ' ' || c == '\t'); +} + +bool isLetter(char c) +{ + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); +} + +bool isDigit(char c) +{ + return (c >= '0' && c <= '9'); +} + +bool isKeyWord(string key) +{ + int len = sizeof(keyWords)/sizeof(keyWords[0]); + int i; + for(i = 0; i < len; i++) + { + if(key == keyWords[i]) + { + return true; + } + } + return false; +} + +string rc_keywordToken(string sline) +{ + if(sline.compare("TEXT_INPUT")==0) + return "1"; + else if(sline.compare("TEXT_OUTPUT")==0) + return "2"; + else if(sline.compare("TEXT_APPEND")==0) + return "3"; + else if(sline.compare("TEXT_INPUT_PLUS")==0) + return "4"; + else if(sline.compare("TEXT_OUTPUT_PLUS")==0) + return "5"; + else if(sline.compare("TEXT_APPEND_PLUS")==0) + return "6"; + else if(sline.compare("BINARY_INPUT")==0) + return "7"; + else if(sline.compare("BINARY_OUTPUT")==0) + return "8"; + else if(sline.compare("BINARY_APPEND")==0) + return "9"; + else if(sline.compare("BINARY_INPUT_PLUS")==0) + return "10"; + else if(sline.compare("BINARY_OUTPUT_PLUS")==0) + return "11"; + else if(sline.compare("BINARY_APPEND_PLUS")==0) + return "12"; + else if(sline.compare("TRUE")==0) + return "1"; + else if(sline.compare("FALSE")==0) + return "0"; + else if(sline.compare("K_0")==0) + return "" + rc_intToString(SDLK_0); + else if(sline.compare("K_1")==0) + return "" + rc_intToString(SDLK_1); + else if(sline.compare("K_2")==0) + return "" + rc_intToString(SDLK_2); + else if(sline.compare("K_3")==0) + return "" + rc_intToString(SDLK_3); + else if(sline.compare("K_4")==0) + return "" + rc_intToString(SDLK_4); + else if(sline.compare("K_5")==0) + return "" + rc_intToString(SDLK_5); + else if(sline.compare("K_6")==0) + return "" + rc_intToString(SDLK_6); + else if(sline.compare("K_7")==0) + return "" + rc_intToString(SDLK_7); + else if(sline.compare("K_8")==0) + return "" + rc_intToString(SDLK_8); + else if(sline.compare("K_9")==0) + return "" + rc_intToString(SDLK_9); + else if(sline.compare("K_A")==0) + return "" + rc_intToString(SDLK_a); + else if(sline.compare("K_AC_BACK")==0) + return "" + rc_intToString(SDLK_AC_BACK); + else if(sline.compare("K_AC_BOOKMARKS")==0) + return "" + rc_intToString(SDLK_AC_BOOKMARKS); + else if(sline.compare("K_AC_FORWARD")==0) + return "" + rc_intToString(SDLK_AC_FORWARD); + else if(sline.compare("K_AC_HOME")==0) + return "" + rc_intToString(SDLK_AC_HOME); + else if(sline.compare("K_AC_REFRESH")==0) + return "" + rc_intToString(SDLK_AC_REFRESH); + else if(sline.compare("K_AC_SEARCH")==0) + return "" + rc_intToString(SDLK_AC_SEARCH); + else if(sline.compare("K_AC_STOP")==0) + return "" + rc_intToString(SDLK_AC_STOP); + else if(sline.compare("K_AGAIN")==0) + return "" + rc_intToString(SDLK_AGAIN); + else if(sline.compare("K_ALTERASE")==0) + return "" + rc_intToString(SDLK_ALTERASE); + else if(sline.compare("K_APPLICATION")==0) + return "" + rc_intToString(SDLK_APPLICATION); + else if(sline.compare("K_AUDIOMUTE")==0) + return "" + rc_intToString(SDLK_AUDIOMUTE); + else if(sline.compare("K_AUDIONEXT")==0) + return "" + rc_intToString(SDLK_AUDIONEXT); + else if(sline.compare("K_AUDIOPLAY")==0) + return "" + rc_intToString(SDLK_AUDIOPLAY); + else if(sline.compare("K_AUDIOPREV")==0) + return "" + rc_intToString(SDLK_AUDIOPREV); + else if(sline.compare("K_AUDIOSTOP")==0) + return "" + rc_intToString(SDLK_AUDIOSTOP); + else if(sline.compare("K_B")==0) + return "" + rc_intToString(SDLK_b); + else if(sline.compare("K_BACKSLASH")==0) + return "" + rc_intToString(SDLK_BACKSLASH); + else if(sline.compare("K_BACKSPACE")==0) + return "" + rc_intToString(SDLK_BACKSPACE); + else if(sline.compare("K_BRIGHTNESSDOWN")==0) + return "" + rc_intToString(SDLK_BRIGHTNESSDOWN); + else if(sline.compare("K_BRIGHTNESSUP")==0) + return "" + rc_intToString(SDLK_BRIGHTNESSUP); + else if(sline.compare("K_C")==0) + return "" + rc_intToString(SDLK_c); + else if(sline.compare("K_CALCULATOR")==0) + return "" + rc_intToString(SDLK_CALCULATOR); + else if(sline.compare("K_CANCEL")==0) + return "" + rc_intToString(SDLK_CANCEL); + else if(sline.compare("K_CAPSLOCK")==0) + return "" + rc_intToString(SDLK_CAPSLOCK); + else if(sline.compare("K_CLEAR")==0) + return "" + rc_intToString(SDLK_CLEAR); + else if(sline.compare("K_CLEARAGAIN")==0) + return "" + rc_intToString(SDLK_CLEARAGAIN); + else if(sline.compare("K_COMPUTER")==0) + return "" + rc_intToString(SDLK_COMPUTER); + else if(sline.compare("K_COPY")==0) + return "" + rc_intToString(SDLK_COPY); + else if(sline.compare("K_CRSEL")==0) + return "" + rc_intToString(SDLK_CRSEL); + else if(sline.compare("K_CURRENCYSUBUNIT")==0) + return "" + rc_intToString(SDLK_CURRENCYSUBUNIT); + else if(sline.compare("K_CURRENCYUNIT")==0) + return "" + rc_intToString(SDLK_CURRENCYUNIT); + else if(sline.compare("K_CUT")==0) + return "" + rc_intToString(SDLK_CUT); + else if(sline.compare("K_D")==0) + return "" + rc_intToString(SDLK_d); + else if(sline.compare("K_DECIMALSEPARATOR")==0) + return "" + rc_intToString(SDLK_DECIMALSEPARATOR); + else if(sline.compare("K_DELETE")==0) + return "" + rc_intToString(SDLK_DELETE); + else if(sline.compare("K_DISPLAYSWITCH")==0) + return "" + rc_intToString(SDLK_DISPLAYSWITCH); + else if(sline.compare("K_DOWN")==0) + return "" + rc_intToString(SDLK_DOWN); + else if(sline.compare("K_E")==0) + return "" + rc_intToString(SDLK_e); + else if(sline.compare("K_EJECT")==0) + return "" + rc_intToString(SDLK_EJECT); + else if(sline.compare("K_END")==0) + return "" + rc_intToString(SDLK_END); + else if(sline.compare("K_EQUAL")==0) + return "" + rc_intToString(SDLK_EQUALS); + else if(sline.compare("K_ESCAPE")==0) + return "" + rc_intToString(SDLK_ESCAPE); + else if(sline.compare("K_EXECUTE")==0) + return "" + rc_intToString(SDLK_EXECUTE); + else if(sline.compare("K_EXSEL")==0) + return "" + rc_intToString(SDLK_EXSEL); + else if(sline.compare("K_F")==0) + return "" + rc_intToString(SDLK_f); + else if(sline.compare("K_F1")==0) + return "" + rc_intToString(SDLK_F1); + else if(sline.compare("K_F2")==0) + return "" + rc_intToString(SDLK_F2); + else if(sline.compare("K_F3")==0) + return "" + rc_intToString(SDLK_F3); + else if(sline.compare("K_F4")==0) + return "" + rc_intToString(SDLK_F4); + else if(sline.compare("K_F5")==0) + return "" + rc_intToString(SDLK_F5); + else if(sline.compare("K_F6")==0) + return "" + rc_intToString(SDLK_F6); + else if(sline.compare("K_F7")==0) + return "" + rc_intToString(SDLK_F7); + else if(sline.compare("K_F8")==0) + return "" + rc_intToString(SDLK_F8); + else if(sline.compare("K_F9")==0) + return "" + rc_intToString(SDLK_F9); + else if(sline.compare("K_F10")==0) + return "" + rc_intToString(SDLK_F10); + else if(sline.compare("K_F11")==0) + return "" + rc_intToString(SDLK_F11); + else if(sline.compare("K_F12")==0) + return "" + rc_intToString(SDLK_F12); + else if(sline.compare("K_F13")==0) + return "" + rc_intToString(SDLK_F13); + else if(sline.compare("K_F14")==0) + return "" + rc_intToString(SDLK_F14); + else if(sline.compare("K_F15")==0) + return "" + rc_intToString(SDLK_F15); + else if(sline.compare("K_F16")==0) + return "" + rc_intToString(SDLK_F16); + else if(sline.compare("K_F17")==0) + return "" + rc_intToString(SDLK_F17); + else if(sline.compare("K_F18")==0) + return "" + rc_intToString(SDLK_F18); + else if(sline.compare("K_F19")==0) + return "" + rc_intToString(SDLK_F19); + else if(sline.compare("K_F20")==0) + return "" + rc_intToString(SDLK_F20); + else if(sline.compare("K_F21")==0) + return "" + rc_intToString(SDLK_F21); + else if(sline.compare("K_F22")==0) + return "" + rc_intToString(SDLK_F22); + else if(sline.compare("K_F23")==0) + return "" + rc_intToString(SDLK_F23); + else if(sline.compare("K_F24")==0) + return "" + rc_intToString(SDLK_F24); + else if(sline.compare("K_FIND")==0) + return "" + rc_intToString(SDLK_FIND); + else if(sline.compare("K_G")==0) + return "" + rc_intToString(SDLK_g); + else if(sline.compare("K_GRAVE")==0) + return "" + rc_intToString(SDLK_BACKQUOTE); + else if(sline.compare("K_H")==0) + return "" + rc_intToString(SDLK_h); + else if(sline.compare("K_HELP")==0) + return "" + rc_intToString(SDLK_HELP); + else if(sline.compare("K_HOME")==0) + return "" + rc_intToString(SDLK_HOME); + else if(sline.compare("K_I")==0) + return "" + rc_intToString(SDLK_i); + else if(sline.compare("K_INSERT")==0) + return "" + rc_intToString(SDLK_INSERT); + else if(sline.compare("K_J")==0) + return "" + rc_intToString(SDLK_j); + else if(sline.compare("K_K")==0) + return "" + rc_intToString(SDLK_k); + else if(sline.compare("K_KBDILLUMDOWN")==0) + return "" + rc_intToString(SDLK_KBDILLUMDOWN); + else if(sline.compare("K_KBDILLUMTOGGLE")==0) + return "" + rc_intToString(SDLK_KBDILLUMTOGGLE); + else if(sline.compare("K_KBDILLUMUP")==0) + return "" + rc_intToString(SDLK_KBDILLUMUP); + else if(sline.compare("KEYPAD_0")==0) + return "" + rc_intToString(SDLK_KP_0); + else if(sline.compare("KEYPAD_00")==0) + return "" + rc_intToString(SDLK_KP_00); + else if(sline.compare("KEYPAD_000")==0) + return "" + rc_intToString(SDLK_KP_000); + else if(sline.compare("KEYPAD_1")==0) + return "" + rc_intToString(SDLK_KP_1); + else if(sline.compare("KEYPAD_2")==0) + return "" + rc_intToString(SDLK_KP_2); + else if(sline.compare("KEYPAD_3")==0) + return "" + rc_intToString(SDLK_KP_3); + else if(sline.compare("KEYPAD_4")==0) + return "" + rc_intToString(SDLK_KP_4); + else if(sline.compare("KEYPAD_5")==0) + return "" + rc_intToString(SDLK_KP_5); + else if(sline.compare("KEYPAD_6")==0) + return "" + rc_intToString(SDLK_KP_6); + else if(sline.compare("KEYPAD_7")==0) + return "" + rc_intToString(SDLK_KP_7); + else if(sline.compare("KEYPAD_8")==0) + return "" + rc_intToString(SDLK_KP_8); + else if(sline.compare("KEYPAD_9")==0) + return "" + rc_intToString(SDLK_KP_9); + else if(sline.compare("KEYPAD_A")==0) + return "" + rc_intToString(SDLK_KP_A); + else if(sline.compare("KEYPAD_AMPERSAND")==0) + return "" + rc_intToString(SDLK_KP_AMPERSAND); + else if(sline.compare("KEYPAD_AT")==0) + return "" + rc_intToString(SDLK_KP_AT); + else if(sline.compare("KEYPAD_B")==0) + return "" + rc_intToString(SDLK_KP_B); + else if(sline.compare("KEYPAD_BACKSPACE")==0) + return "" + rc_intToString(SDLK_KP_BACKSPACE); + else if(sline.compare("KEYPAD_BINARY")==0) + return "" + rc_intToString(SDLK_KP_BINARY); + else if(sline.compare("KEYPAD_C")==0) + return "" + rc_intToString(SDLK_KP_C); + else if(sline.compare("KEYPAD_CLEAR")==0) + return "" + rc_intToString(SDLK_KP_CLEAR); + else if(sline.compare("KEYPAD_CLEARENTRY")==0) + return "" + rc_intToString(SDLK_KP_CLEARENTRY); + else if(sline.compare("KEYPAD_COLON")==0) + return "" + rc_intToString(SDLK_KP_COLON); + else if(sline.compare("KEYPAD_COMMA")==0) + return "" + rc_intToString(SDLK_KP_COMMA); + else if(sline.compare("KEYPAD_D")==0) + return "" + rc_intToString(SDLK_KP_D); + else if(sline.compare("KEYPAD_DBLAMPERSAND")==0) + return "" + rc_intToString(SDLK_KP_DBLAMPERSAND); + else if(sline.compare("KEYPAD_DBLVERTICALBAR")==0) + return "" + rc_intToString(SDLK_KP_DBLVERTICALBAR); + else if(sline.compare("KEYPAD_DECIMAL")==0) + return "" + rc_intToString(SDLK_KP_DECIMAL); + else if(sline.compare("KEYPAD_DIVIDE")==0) + return "" + rc_intToString(SDLK_KP_DIVIDE); + else if(sline.compare("KEYPAD_E")==0) + return "" + rc_intToString(SDLK_KP_E); + else if(sline.compare("KEYPAD_ENTER")==0) + return "" + rc_intToString(SDLK_KP_ENTER); + else if(sline.compare("KEYPAD_EQUAL")==0) + return "" + rc_intToString(SDLK_KP_EQUALS); + else if(sline.compare("KEYPAD_EQUALAS400")==0) + return "" + rc_intToString(SDLK_KP_EQUALSAS400); + else if(sline.compare("KEYPAD_EXCLAM")==0) + return "" + rc_intToString(SDLK_KP_EXCLAM); + else if(sline.compare("KEYPAD_F")==0) + return "" + rc_intToString(SDLK_KP_F); + else if(sline.compare("KEYPAD_GREATER")==0) + return "" + rc_intToString(SDLK_KP_GREATER); + else if(sline.compare("KEYPAD_HASH")==0) + return "" + rc_intToString(SDLK_KP_HASH); + else if(sline.compare("KEYPAD_HEXADECIMAL")==0) + return "" + rc_intToString(SDLK_KP_HEXADECIMAL); + else if(sline.compare("KEYPAD_LEFTBRACE")==0) + return "" + rc_intToString(SDLK_KP_LEFTBRACE); + else if(sline.compare("KEYPAD_LEFTPAREN")==0) + return "" + rc_intToString(SDLK_KP_LEFTPAREN); + else if(sline.compare("KEYPAD_LESS")==0) + return "" + rc_intToString(SDLK_KP_LESS); + else if(sline.compare("KEYPAD_MEMADD")==0) + return "" + rc_intToString(SDLK_KP_MEMADD); + else if(sline.compare("KEYPAD_MEMCLEAR")==0) + return "" + rc_intToString(SDLK_KP_MEMCLEAR); + else if(sline.compare("KEYPAD_MEMDIVIDE")==0) + return "" + rc_intToString(SDLK_KP_MEMDIVIDE); + else if(sline.compare("KEYPAD_MEMMULTIPLY")==0) + return "" + rc_intToString(SDLK_KP_MEMMULTIPLY); + else if(sline.compare("KEYPAD_OCTAL")==0) + return "" + rc_intToString(SDLK_KP_OCTAL); + else if(sline.compare("KEYPAD_PERCENT")==0) + return "" + rc_intToString(SDLK_KP_PERCENT); + else if(sline.compare("KEYPAD_PERIOD")==0) + return "" + rc_intToString(SDLK_KP_PERIOD); + else if(sline.compare("KEYPAD_PLUS")==0) + return "" + rc_intToString(SDLK_KP_PLUS); + else if(sline.compare("KEYPAD_PLUSMINUS")==0) + return "" + rc_intToString(SDLK_KP_PLUSMINUS); + else if(sline.compare("KEYPAD_POWER")==0) + return "" + rc_intToString(SDLK_KP_POWER); + else if(sline.compare("KEYPAD_RIGHTBRACE")==0) + return "" + rc_intToString(SDLK_KP_RIGHTBRACE); + else if(sline.compare("KEYPAD_RIGHTPAREN")==0) + return "" + rc_intToString(SDLK_KP_RIGHTPAREN); + else if(sline.compare("KEYPAD_SPACE")==0) + return "" + rc_intToString(SDLK_KP_SPACE); + else if(sline.compare("KEYPAD_TAB")==0) + return "" + rc_intToString(SDLK_KP_TAB); + else if(sline.compare("KEYPAD_VERTICALBAR")==0) + return "" + rc_intToString(SDLK_KP_VERTICALBAR); + else if(sline.compare("KEYPAD_XOR")==0) + return "" + rc_intToString(SDLK_KP_XOR); + else if(sline.compare("K_L")==0) + return "" + rc_intToString(SDLK_l); + else if(sline.compare("K_L")==0) + return "" + rc_intToString(SDLK_l); + else if(sline.compare("K_LALT")==0) + return "" + rc_intToString(SDLK_LALT); + else if(sline.compare("K_LCTRL")==0) + return "" + rc_intToString(SDLK_LCTRL); + else if(sline.compare("K_LEFT")==0) + return "" + rc_intToString(SDLK_LEFT); + else if(sline.compare("K_LEFTBRACKET")==0) + return "" + rc_intToString(SDLK_LEFTBRACKET); + else if(sline.compare("K_LGUI")==0) + return "" + rc_intToString(SDLK_LGUI); + else if(sline.compare("K_LSHIFT")==0) + return "" + rc_intToString(SDLK_LSHIFT); + else if(sline.compare("K_M")==0) + return "" + rc_intToString(SDLK_m); + else if(sline.compare("K_MAIL")==0) + return "" + rc_intToString(SDLK_MAIL); + else if(sline.compare("K_MEDIASELECT")==0) + return "" + rc_intToString(SDLK_MEDIASELECT); + else if(sline.compare("K_MENU")==0) + return "" + rc_intToString(SDLK_MENU); + else if(sline.compare("K_MINUS")==0) + return "" + rc_intToString(SDLK_MINUS); + else if(sline.compare("K_MODESWITCH")==0) + return "" + rc_intToString(SDLK_MODE); + else if(sline.compare("K_MUTE")==0) + return "" + rc_intToString(SDLK_MUTE); + else if(sline.compare("K_N")==0) + return "" + rc_intToString(SDLK_n); + else if(sline.compare("K_NUMLOCK")==0) + return "" + rc_intToString(SDLK_NUMLOCKCLEAR); + else if(sline.compare("K_O")==0) + return "" + rc_intToString(SDLK_o); + else if(sline.compare("K_OPER")==0) + return "" + rc_intToString(SDLK_OPER); + else if(sline.compare("K_OUT")==0) + return "" + rc_intToString(SDLK_OUT); + else if(sline.compare("K_P")==0) + return "" + rc_intToString(SDLK_p); + else if(sline.compare("K_PAGEDOWN")==0) + return "" + rc_intToString(SDLK_PAGEDOWN); + else if(sline.compare("K_PAGEUP")==0) + return "" + rc_intToString(SDLK_PAGEUP); + else if(sline.compare("K_PASTE")==0) + return "" + rc_intToString(SDLK_PASTE); + else if(sline.compare("K_PAUSE")==0) + return "" + rc_intToString(SDLK_PAUSE); + else if(sline.compare("K_POWER")==0) + return "" + rc_intToString(SDLK_POWER); + else if(sline.compare("K_PRINTSCREEN")==0) + return "" + rc_intToString(SDLK_PRINTSCREEN); + else if(sline.compare("K_PRIOR")==0) + return "" + rc_intToString(SDLK_PRIOR); + else if(sline.compare("K_Q")==0) + return "" + rc_intToString(SDLK_q); + else if(sline.compare("K_R")==0) + return "" + rc_intToString(SDLK_r); + else if(sline.compare("K_RALT")==0) + return "" + rc_intToString(SDLK_RALT); + else if(sline.compare("K_RCTRL")==0) + return "" + rc_intToString(SDLK_RCTRL); + else if(sline.compare("K_RETURN")==0) + return "" + rc_intToString(SDLK_RETURN); + else if(sline.compare("K_RETURN2")==0) + return "" + rc_intToString(SDLK_RETURN2); + else if(sline.compare("K_RGUI")==0) + return "" + rc_intToString(SDLK_RGUI); + else if(sline.compare("K_RIGHT")==0) + return "" + rc_intToString(SDLK_RIGHT); + else if(sline.compare("K_RIGHTBRACKET")==0) + return "" + rc_intToString(SDLK_RIGHTBRACKET); + else if(sline.compare("K_RSHIFT")==0) + return "" + rc_intToString(SDLK_RSHIFT); + else if(sline.compare("K_S")==0) + return "" + rc_intToString(SDLK_s); + else if(sline.compare("K_SCROLLLOCK")==0) + return "" + rc_intToString(SDLK_SCROLLLOCK); + else if(sline.compare("K_SELECT")==0) + return "" + rc_intToString(SDLK_SELECT); + else if(sline.compare("K_SEMICOLON")==0) + return "" + rc_intToString(SDLK_SEMICOLON); + else if(sline.compare("K_SEPARATOR")==0) + return "" + rc_intToString(SDLK_SEPARATOR); + else if(sline.compare("K_SLASH")==0) + return "" + rc_intToString(SDLK_SLASH); + else if(sline.compare("K_SLEEP")==0) + return "" + rc_intToString(SDLK_SLEEP); + else if(sline.compare("K_SPACE")==0) + return "" + rc_intToString(SDLK_SPACE); + else if(sline.compare("K_STOP")==0) + return "" + rc_intToString(SDLK_STOP); + else if(sline.compare("K_SYSREQ")==0) + return "" + rc_intToString(SDLK_SYSREQ); + else if(sline.compare("K_T")==0) + return "" + rc_intToString(SDLK_t); + else if(sline.compare("K_TAB")==0) + return "" + rc_intToString(SDLK_TAB); + else if(sline.compare("K_THOUSANDSEPARATOR")==0) + return "" + rc_intToString(SDLK_THOUSANDSSEPARATOR); + else if(sline.compare("K_U")==0) + return "" + rc_intToString(SDLK_u); + else if(sline.compare("K_UNDO")==0) + return "" + rc_intToString(SDLK_UNDO); + else if(sline.compare("K_UNKNOWN")==0) + return "" + rc_intToString(SDLK_UNKNOWN); + else if(sline.compare("K_UP")==0) + return "" + rc_intToString(SDLK_UP); + else if(sline.compare("K_V")==0) + return "" + rc_intToString(SDLK_v); + else if(sline.compare("K_VOLUMEDOWN")==0) + return "" + rc_intToString(SDLK_VOLUMEDOWN); + else if(sline.compare("K_VOLUMEUP")==0) + return "" + rc_intToString(SDLK_VOLUMEUP); + else if(sline.compare("K_W")==0) + return "" + rc_intToString(SDLK_w); + else if(sline.compare("K_WWW")==0) + return "" + rc_intToString(SDLK_WWW); + else if(sline.compare("K_X")==0) + return "" + rc_intToString(SDLK_x); + else if(sline.compare("K_Y")==0) + return "" + rc_intToString(SDLK_y); + else if(sline.compare("K_Z")==0) + return "" + rc_intToString(SDLK_z); + else if(sline.compare("WINDOWPOS_CENTERED")==0) + return "" + rc_intToString(SDL_WINDOWPOS_CENTERED); + else if(sline.compare("HAT_RIGHT")==0) + return "" + rc_intToString(SDL_HAT_RIGHT); + else if(sline.compare("HAT_LEFT")==0) + return "" + rc_intToString(SDL_HAT_LEFT); + else if(sline.compare("HAT_UP")==0) + return "" + rc_intToString(SDL_HAT_UP); + else if(sline.compare("HAT_DOWN")==0) + return "" + rc_intToString(SDL_HAT_DOWN); + else if(sline.compare("HAT_LEFTUP")==0) + return "" + rc_intToString(SDL_HAT_LEFTUP); + else if(sline.compare("HAT_LEFTDOWN")==0) + return "" + rc_intToString(SDL_HAT_LEFTDOWN); + else if(sline.compare("HAT_RIGHTUP")==0) + return "" + rc_intToString(SDL_HAT_RIGHTUP); + else if(sline.compare("HAT_RIGHTDOWN")==0) + return "" + rc_intToString(SDL_HAT_RIGHTDOWN); + else if(sline.compare("HAT_CENTERED")==0) + return "" + rc_intToString(SDL_HAT_CENTERED); + else if(sline.compare("BLENDMODE_NONE")==0) + return "" + rc_intToString(SDL_BLENDMODE_NONE); + else if(sline.compare("BLENDMODE_BLEND")==0) + return "" + rc_intToString(SDL_BLENDMODE_BLEND); + else if(sline.compare("BLENDMODE_ADD")==0) + return "" + rc_intToString(SDL_BLENDMODE_ADD); + else if(sline.compare("BLENDMODE_MOD")==0) + return "" + rc_intToString(SDL_BLENDMODE_MOD); + else if(sline.compare("ANDROID_EXTERNAL_STORAGE_READ")==0) + return "1"; + else if(sline.compare("ANDROID_EXTERNAL_STORAGE_WRITE")==0) + return "2"; + else if(sline.compare("POWERSTATE_UNKNOWN")==0) + return "0"; + else if(sline.compare("POWERSTATE_ON_BATTERY")==0) + return "1"; + else if(sline.compare("POWERSTATE_NO_BATTERY")==0) + return "2"; + else if(sline.compare("POWERSTATE_CHARGING")==0) + return "3"; + else if(sline.compare("POWERSTATE_CHARGED")==0) + return "4"; + else if(sline.compare("WINDOW_VISIBLE")==0) + return "" + rc_intToString(SDL_WINDOW_SHOWN); + else if(sline.compare("WINDOW_FULLSCREEN")==0) + return "" + rc_intToString(SDL_WINDOW_FULLSCREEN_DESKTOP); + else if(sline.compare("WINDOW_RESIZABLE")==0) + return "" + rc_intToString(SDL_WINDOW_RESIZABLE); + else if(sline.compare("WINDOW_BORDERLESS")==0) + return "" + rc_intToString(SDL_WINDOW_BORDERLESS); + else if(sline.compare("WINDOW_HIGHDPI")==0) + return "" + rc_intToString(SDL_WINDOW_ALLOW_HIGHDPI); + else if(sline.compare("WINDOW_HIDDEN")==0) + return "" + rc_intToString(SDL_WINDOW_HIDDEN); + else if(sline.compare("ON_ERROR_CONTINUE")==0) + return "0"; + else if(sline.compare("ON_ERROR_STOP")==0) + return "1"; + else + { + for(int i = 0; i < rc_constants.size(); i++) + { + if(rc_constants[i].const_name.compare(sline)==0) + { + for(int c_token_index=0; c_token_index < rc_constants[i].const_tokens.size(); c_token_index++) + tmp_token.push_back(rc_constants[i].const_tokens[c_token_index]); + + return ""; + } + } + } + + return ""; +} + +void output_tokens() +{ + //return; + for(int i = 0; i < tmp_token.size(); i++) + { + try + { + cout << i << ":" << tmp_token.at(i) << endl; + } + catch(out_of_range& e) + { + cout << "Token Out of Range Error: " << e.what() << endl; + } + } +} + +void clearTokens() +{ + tmp_token.clear(); + token.clear(); +} + +#endif // TOKENIZER_H_INCLUDED diff --git a/rcbasic_build/vm_asm b/rcbasic_build/vm_asm new file mode 100644 index 0000000..00076f2 --- /dev/null +++ b/rcbasic_build/vm_asm @@ -0,0 +1,285 @@ +------------------------- +|types of parameters +------------------------- +raw_number = starting character (0-9) +n# = starting character n followed by # (# is a number denoting the number register to use) +s# = starting character s followed by # (# is a number denoting the string register to use) +u# = starting character u followed by # (# is a number denoting the user_type register to use) +r# = starting character r followed by # (# is a number denoting the reference register to use) //references are set when obj_get or mov(34) or mov(38) is called +!id = starting character is ! followed id (id is a number denoting the id vector position) //it can be used for any integer argument as well as id's +@[data_address] = starting character is @ followed by the number specifying the offset in the data segment + +---------------------------------------- +|SYSTEM AND VM OPERATION +--------------------------------------- + +0 - end +1 - dbg uint uint uint // arguments are (debug_function, file_index, line_number) + +--------------------------------------- +|MOVING DATA +---------------------------------------- + +32 - mov n# n# +33 - mov n# raw_number +34 - mov n# !id +35 - mov !id n# + +36 - mov$ s# s# +37 - mov$ s# @[data_address] +38 - mov$ s# !id +39 - mov$ !id s# + +40 - mov_r r# n# +41 - mov_r$ r# s# + +42 - mov_type u# u# //copy user types and arrays NOTE: This will do the same thing mov_r does by setting the reference pointed to by the first arg + +-------------------------------------- +|OPERATORS +------------------------------------- + +43 - add$ s# s# + +44 - add n# n# +45 - sub n# n# +46 - mul n# n# +47 - div n# n# +48 - pow n# n# +49 - mod n# n# +50 - shl n# n# +51 - shr n# n# +52 - and n# n# +53 - or n# n# +54 - xor n# n# +55 - not n# n# + +-------------------------------------- +|COMPARE AND JUMP +-------------------------------------- +CMP_EQUAL +CMP_NOT_EQUAL +CMP_GREATER +CMP_GREATER_EQUAL +CMP_LESS +CMP_LESS_EQUAL +------------------------------------- + +56 - cmp n# n# +57 - cmp$ s# s# +58 - cmp_u n# n# + +59 - jmp n# +60 - jmp @[address] +61 - je n# +62 - je @[address] +63 - jne n# +64 - jne @[address] +65 - jg n# +66 - jg @[address] +67 - jge n# +68 - jge @[address] +69 - jl n# +70 - jl @[address] +71 - jle n# +72 - jle @[address] + +-------------------------------------- +|OBJECTS (USER TYPES AND ARRAYS) +-------------------------------------- +OBJ_CURRENT_POSITION +OBJ_CURRENT_TYPE +-------------------------------------- + +73 - obj_num !id +74 - obj_num1 !id n# (n# is the first dimension) +75 - obj_num2 !id n# n# +76 - obj_num3 !id n# n# n# + +77 - obj_str !id +78 - obj_str1 !id n# (n# is the first dimension) +79 - obj_str2 !id n# n# +80 - obj_str3 !id n# n# n# + +81 - obj_usr !id +82 - obj_usr1 !id n# (n# is the first dimension) +83 - obj_usr2 !id n# n# +84 - obj_usr3 !id n# n# n# + +85 - obj_get n# +86 - obj_get$ s# + +87 - obj_set n# +88 - obj_set s$ + +89 - clear_obj + +90 - dim_type !id raw_number (user_type) +91 - dim_type1 !id raw_number (user type) n# (dim1) +92 - dim_type2 !id raw_number (user type) n# (dim1) n# (dim2) +93 - dim_type3 !id raw_number (user type) n# (dim1) n# (dim2) n# (dim3) + +94 - dim_num1 !id n# (dim1) +95 - dim_num2 !id n# (dim1) n# (dim2) +96 - dim_num3 !id n# (dim1) n# (dim2) n# (dim3) + +97 - dim_str1 !id n# (dim1) +98 - dim_str2 !id n# (dim1) n# (dim2) +99 - dim_str3 !id n# (dim1) n# (dim2) n# (dim3) + +-------------------------------------------- +|STACKS +-------------------------------------------- + NUM_STACK + STR_STACK +-------------------------------------------- + +100 - delete !id +101 - delete$ !id + +102 - push n# +103 - push !id + +104 - push$ s# +105 - push$ !id + +106 - push_empty$ + +107 - pop n# +108 - pop !id + +109 - pop$ s$ +110 - pop$ !id + +111 - get_stack_size n# +112 - get_stack_size$ n# + +113 - clear_stack +114 - clear_stack$ + +--------------------------------------------- +|LOOP +--------------------------------------------- + LOOP_STACK +--------------------------------------------- + +115 - while n# +116 - wend @address 'using jmp in parser for now + +117 - for !id n# (starting value) n# (ending value) n#(step value) +118 - next @address + +119 - do +120 - loop +121 - loop_while n# +122 - loop_until n# + +123 - pop_loop_stack + +------------------------------------------ +|FUNCTIONS AND SUB ROUTINES +------------------------------------------ + FUNCTION_STACK +------------------------------------------ + +124 - gosub @[address] +125 - return + +----------------------------------------- +|POINTERS +----------------------------------------- +126 - ptr !id n# +127 - ptr$ !id s# + +------------------------------------------ +|ADDED STUFF 'Because I didn't plan this design that well +------------------------------------------ + +128 - print n# +129 - print$ s# +130 - func raw_number (built-in function index) +131 - push raw_number +132 - println +133 - mov n# %CMP_FLAG +134 - cmp n# raw_number +135 - mov_arr n# !id +136 - mov_arr$ s# !id +137 - pop_ptr n# +138 - preset !id +139 - preset$ !id + +140 - redim1 !id n# +141 - redim2 !id n# n# +142 - redim3 !id n# n# n# + +143 - redim1$ !id n# +144 - redim2$ !id n# n# +145 - redim3$ !id n# n# n# + +146 - for_offset_arr1 n# +147 - for_offset_arr2 n# n# +148 - for_offset_arr3 n# n# n# + +149 - for_offset_0 + +150 - end_x n# + +151 - lval n# +152 - lval !id +153 - lval @[address] + +154 - lval$ s# +155 - lval$ !id + +// ---- New in 4.0 --------- +156 - obj_usr_n !id +157 - obj_usr_n1 !id n# +158 - obj_usr_n2 !id n# n# +159 - obj_usr_n3 !id n# n# n# + +160 - obj_usr_s !id +161 - obj_usr_s1 !id n# +162 - obj_usr_s2 !id n# n# +163 - obj_usr_s3 !id n# n# n# + +164 - obj_usr_get n# +165 - obj_usr_get s# +166 - obj_usr_get u# // gets the value and sets the reference + +167 - uref_ptr !id u# + +168 - mov_type !id u# //copy user types and arrays + +169 - push_t u# +170 - push_t !id + +171 - pop_t u# +172 - pop_t !id + +173 - push_t_null + +174 - delete_t !id + +175 - dim_type u# raw_number (user_type) +176 - dim_type1 u# raw_number (user type) n# (dim1) +177 - dim_type2 u# raw_number (user type) n# (dim1) n# (dim2) +178 - dim_type3 u# raw_number (user type) n# (dim1) n# (dim2) n# (dim3) + +179 - dim_tfield raw_number (user_type) raw_number (member_type) raw_number (member_index) raw_number (dimensions) n# (dim1) n# (dim2) n# (dim3) + +180 - obj_usr_init !id +181 - obj_usr_init1 !id n# (n# is the first dimension) +182 - obj_usr_init2 !id n# n# +183 - obj_usr_init3 !id n# n# n# + +184 - obj_usr_init u# +185 - obj_usr_init1 u# n# (n# is the first dimension) +186 - obj_usr_init2 u# n# n# +187 - obj_usr_init3 u# n# n# n# + +188 - preset_t !id raw_number (user_type) +189 - preset_t1 !id raw_number (user_type) n# +190 - preset_t2 !id raw_number (user_type) n# n# +191 - preset_t3 !id raw_number (user_type) n# n# n# + + diff --git a/rcbasic_runtime/main.cpp b/rcbasic_runtime/main.cpp new file mode 100644 index 0000000..a83bb09 --- /dev/null +++ b/rcbasic_runtime/main.cpp @@ -0,0 +1,5653 @@ +//#define RCBASIC_DEBUG 1 + +#include "rc_os_defines.h" + +#ifdef RC_WEB +#include +#endif + +#ifdef RC_IOS +#define RC_GETCWD +#include +#endif + +#ifdef RC_MAC +#define RC_GETCWD +#include +#endif + +#ifdef RC_ANDROID +#define RC_GETCWD +#endif + +#ifdef RC_WINDOWS +#include +#define _UNICODE +#endif // RC_WINDOWS + + +#ifdef RC_ANDROID + #include + #include + #include + #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__)) +#endif // RC_ANDROID + +#include +#include +#include +#ifdef RC_ANDROID + #include "SDL.h" +#else + #include +#endif +#include +#include +#include +#include +#include +#include "rc_defines.h" +#include "rc_stdlib.h" +#include "rc_media.h" +#include "rc_matrix.h" +#include "rc_process.h" +#include "rc_geometry.h" + +using namespace std; + +#define LESS_FLAG 0 +#define LESS_EQUAL_FLAG 1 +#define GREATER_FLAG 2 +#define GREATER_EQUAL_FLAG 3 +#define EQUAL_FLAG 4 +#define NOT_EQUAL_FLAG 5 + +#define CODE_SEGMENT 0 +#define DATA_SEGMENT 1 + +#define RC_UDT_TYPE_NUM 0 +#define RC_UDT_TYPE_STR 1 +#define RC_UDT_TYPE_USR 2 + + +bool CMP_FLAG_EQUAL = false; +bool CMP_FLAG_LESS = false; +bool CMP_FLAG_LESS_EQUAL = false; +bool CMP_FLAG_GREATER = false; +bool CMP_FLAG_GREATER_EQUAL = false; +bool CMP_FLAG_NOT_EQUAL = false; + +string rcbasic_runtime_path = ""; + +struct n_value +{ + vector value; +}; + +struct s_value +{ + vector value; +}; + +struct rc_vm_n +{ + double value; + n_value * r; //reference + uint64_t r_index; + + #ifdef RCBASIC_DEBUG + uint64_t dbg_var_index; + #endif // RCBASIC_DEBUG +}; + +struct rc_vm_s +{ + string value; + s_value * r; + uint64_t r_index; + + #ifdef RCBASIC_DEBUG + uint64_t dbg_var_index; + #endif // RCBASIC_DEBUG +}; + +struct rc_numId +{ + n_value nid_value; + int dimensions; + uint64_t dim[3]; + uint64_t byref_offset; + + n_value * nref; + + #ifdef RCBASIC_DEBUG + bool is_debug_var; + uint64_t dbg_var_index; + #endif // RCBASIC_DEBUG +}; + +struct rc_strId +{ + s_value sid_value; + int dimensions; + uint64_t dim[3]; + uint64_t byref_offset; + + s_value * sref; + + #ifdef RCBASIC_DEBUG + bool is_debug_var; + uint64_t dbg_var_index; + #endif // RCBASIC_DEBUG +}; + +struct rc_udtFieldSize +{ + uint64_t dim[3]; +}; + +struct rc_udtDefinition +{ + int num_fields; + vector field_type; // 0 - num, 1 - str, 2 - UDT + vector field_type_index; //if field type is UDT + vector field_dimensions; + vector field_size; +}; + +vector rc_types; + +struct rc_usrId +{ + vector num_var; + vector str_var; + vector uid_value; + int dimensions; + uint64_t dim[3]; + uint64_t byref_offset; + int udt_index; //index of the type definition in rc_types + + rc_usrId * var_ref; + uint64_t var_ref_index; + + bool preset_init = false; + + #ifdef RCBASIC_DEBUG + bool is_debug_var; + uint64_t dbg_var_index; + #endif // RCBASIC_DEBUG +}; + +struct rc_loop +{ + rc_numId * counter; + double f_end; + double f_step; + bool isNegative; + uint64_t counter_offset; + #ifdef RCBASIC_DEBUG + uint64_t counter_dim[3]; + #endif // RCBASIC_DEBUG +}; + +uint64_t for_offset_index[3]; +int for_offset_dimensions = 0; + +union rc_double +{ + double f; + unsigned char data[sizeof(double)]; +}; + +union rc_int +{ + uint64_t i; + unsigned char data[sizeof(uint64_t)]; +}; + +struct addr_entry +{ + uint64_t ptr_id; + void * ptr_addr; + int type; +}; + +stack byref_addr_table; +stack byref_var_byref_offset; + +uint64_t n_count = 0; +uint64_t s_count = 0; +uint64_t u_count = 0; +uint64_t n_stack_size = 0; +uint64_t s_stack_size = 0; +uint64_t u_stack_size = 0; +uint64_t loop_stack_size = 0; +uint64_t numID_count = 0; +uint64_t strID_count = 0; +uint64_t usrID_count = 0; +uint64_t code_segment_size = 0; +uint64_t data_segment_size = 0; + +struct n_obj_struct +{ + n_value * obj_val; + uint64_t index; + + #ifdef RCBASIC_DEBUG + uint64_t nid; + #endif // RCBASIC_DEBUG +}; + +struct s_obj_struct +{ + s_value * obj_val; + uint64_t index; + + #ifdef RCBASIC_DEBUG + uint64_t sid; + #endif // RCBASIC_DEBUG +}; + +struct u_obj_struct +{ + rc_usrId * obj_ref; + + rc_numId * num_ref; + rc_strId * str_ref; + + uint64_t index; +}; + +n_obj_struct num_object; +s_obj_struct str_object; +u_obj_struct usr_object; + +rc_vm_n * vm_n; +rc_vm_s * vm_s; +rc_usrId * vm_u; + +stack n_stack; +stack s_stack; +stack u_stack; +stack loop_stack; + +int current_n_stack_count = 0; +int current_s_stack_count = 0; +int current_u_stack_count = 0; +int current_loop_stack_count = 0; + +rc_numId * num_var; +rc_strId * str_var; +rc_usrId * usr_var; + +unsigned char ** segment; + +int current_segment = CODE_SEGMENT; +uint64_t current_address = 0; + +stack gosub_return_addr; + +rc_int readint_val; +rc_double readdouble_val; + +vector arr_ref_id(2); + +int rcbasic_exit_code = 0; + +#ifdef RCBASIC_DEBUG +#define RCBASIC_DEBUG_VAR_NUM 0 +#define RCBASIC_DEBUG_VAR_ARR_NUM 1 +#define RCBASIC_DEBUG_VAR_BYREF_NUM 2 +#define RCBASIC_DEBUG_VAR_STR 3 +#define RCBASIC_DEBUG_VAR_ARR_STR 4 +#define RCBASIC_DEBUG_VAR_BYREF_STR 5 + +#define RCBASIC_DEBUG_ACCESS_GET 0 +#define RCBASIC_DEBUG_ACCESS_SET 1 + +struct rcbasic_debug_access_status +{ + int type; + int dimensions; + int dim[3]; + double num_val; + string str_val; + int reg; + bool is_error = false; +}; + +struct rcbasic_debug_vars +{ + int type; + string scope; + string name; + int index; + vector usage_data; +}; + +vector dbg_vars; +vector dbg_files; + +uint64_t current_src_line = 1; +uint64_t current_src_file = 0; + +#define DBG_DIV_BY_ZERO "Divide By Zero" +#define DBG_NEGATIVE_INDEX "Negative Array Index" +#define DBG_INDEX_EXCEEDS_SIZE "Array Index is Greater than Array Size" +#define DBG_DIM_LEQ_ZERO "Array Size must be greater than Zero" +#define DBG_REDIM_LEQ_ZERO "Array Size must be greater than Zero" + +bool dbg_error_found = false; +string dbg_error_message = ""; + + +void loadDebugData(string sym_file, string inc_file) +{ + fstream f(sym_file, fstream::in); + + string f_line; + + string type_str = ""; + rcbasic_debug_vars tmp; + + while(!f.eof()) + { + getline(f, f_line); + + type_str = f_line.substr(0, f_line.find_first_of(" ")); + + if(type_str.compare("N")==0) + { + tmp.type = RCBASIC_DEBUG_VAR_NUM; + } + else if(type_str.compare("AN")==0) + { + tmp.type = RCBASIC_DEBUG_VAR_ARR_NUM; + } + else if(type_str.compare("BN")==0) + { + tmp.type = RCBASIC_DEBUG_VAR_BYREF_NUM; + } + else if(type_str.compare("S")==0) + { + tmp.type = RCBASIC_DEBUG_VAR_STR; + } + else if(type_str.compare("AS")==0) + { + tmp.type = RCBASIC_DEBUG_VAR_ARR_STR; + } + else if(type_str.compare("BS")==0) + { + tmp.type = RCBASIC_DEBUG_VAR_BYREF_STR; + } + + f_line = f_line.substr(f_line.find_first_of(" ")+1); + tmp.scope = f_line.substr(0, f_line.find_first_of(" ")); + + f_line = f_line.substr(f_line.find_first_of(" ")+1); + tmp.name = f_line.substr(0, f_line.find_first_of(" ")); + + f_line = f_line.substr(f_line.find_first_of(" ")+1); + tmp.index = atoi(f_line.c_str()); + + switch(tmp.type) + { + case RCBASIC_DEBUG_VAR_NUM: + case RCBASIC_DEBUG_VAR_ARR_NUM: + case RCBASIC_DEBUG_VAR_BYREF_NUM: + num_var[tmp.index].dbg_var_index = dbg_vars.size(); + num_var[tmp.index].is_debug_var = true; + break; + case RCBASIC_DEBUG_VAR_STR: + case RCBASIC_DEBUG_VAR_ARR_STR: + case RCBASIC_DEBUG_VAR_BYREF_STR: + str_var[tmp.index].dbg_var_index = dbg_vars.size(); + str_var[tmp.index].is_debug_var = true; + break; + } + + dbg_vars.push_back(tmp); + } + + f.close(); + + f.open(inc_file, fstream::in); + + while(!f.eof()) + { + getline(f, f_line); + if(f_line.find_first_not_of(" ")!=string::npos) + dbg_files.push_back(f_line); + } + + f.close(); +} + +string dbg_format_string(string dbg_str_val) +{ + string rtn = dbg_str_val; + rtn = rc_intern_replace(rtn, "\n", "\\n"); + rtn = rc_intern_replace(rtn, "\r", "\\r"); + rtn = rc_intern_replace(rtn, "\t", "\\t"); + return rtn; +} + +void output_debug_message() +{ + //cout << "output debug messages" << endl; + + if(rc_intern_fileExist("rcbasic_dbg.sp") && (!dbg_error_found)) + { + //if(rc_intern_fileExist("rcbasic.dbgm")) + // rc_intern_fileDelete("rcbasic.dbgm"); + + /*if(rc_intern_fileExist("rcbasic_dbg.rt")) + { + while(rc_intern_fileExist("rcbasic_dbg.rt")) + { + rc_intern_fileDelete("rcbasic_dbg.rt"); //keep trying to delete file + } + + fstream f("rcbasic_dbg.cl", fstream::out); //generate this file to let the client know it has ownership + f.close(); + }*/ + for(int i = 0; i < dbg_vars.size(); i++) + { + dbg_vars[i].usage_data.clear(); + } + return; + } + + + fstream f("rcbasic.dbgm", fstream::out | fstream::trunc); + + f << "SRC " << dbg_files[current_src_file] << endl; + f << "LN " << current_src_line << endl; + + for(int i = 0; i < dbg_vars.size(); i++) + { + for(int usage = 0; usage < dbg_vars[i].usage_data.size(); usage++) + { + f << ((dbg_vars[i].type < RCBASIC_DEBUG_VAR_STR) ? "N" : "S") << " " + << i << " " << dbg_vars[i].usage_data[usage].type << " " + << (dbg_vars[i].usage_data[usage].is_error ? "E" : "G") << " " + << dbg_vars[i].usage_data[usage].dimensions << " " + << dbg_vars[i].usage_data[usage].dim[0] << " " + << dbg_vars[i].usage_data[usage].dim[1] << " " + << dbg_vars[i].usage_data[usage].dim[2] << " " + << ((dbg_vars[i].type < RCBASIC_DEBUG_VAR_STR) ? "VAL=" + rc_intern_str(dbg_vars[i].usage_data[usage].num_val) : "VAL=" + dbg_format_string(dbg_vars[i].usage_data[usage].str_val)) + << endl; + } + dbg_vars[i].usage_data.clear(); + //f << ((dbg_vars[i].type==0) ? " N " : " S ") << dbg_vars[i].name << " " << ((dbg_vars[i].type==0) ? num_var[dbg_vars[i].index]. + } + + if(dbg_error_found) + { + f << "E " << dbg_error_message << endl; + } + + f.close(); + + + + f.open("rcbasic_dbg.cl", fstream::out); //generate this file to let the client know it has ownership + f.close(); + + while(!rc_intern_fileExist("rcbasic_dbg.rt")){} //wait for client to generate this file so we know its done reading the previous output + + while(rc_intern_fileExist("rcbasic_dbg.rt")) + { + rc_intern_fileDelete("rcbasic_dbg.rt"); //keep trying to delete file + } + +} + +#endif // RCBASIC_DEBUG + +//needed by internal functions so i am declaring it here +void lval_151(int n1); +void lval_152(uint64_t nid); +void lval_153(uint64_t lval_addr); +void lval_154(int s1); +void lval_155(uint64_t sid); +void pop_ptr_137(uint64_t n); + +uint64_t rcbasic_readInt() +{ + uint64_t i; + SDL_RWread(rc_fstream[0], &i, sizeof(uint64_t), 1); + return i; +} + + +bool rcbasic_load(string filename) +{ + char rc[5]; + + rc_fstream[0] = SDL_RWFromFile(filename.c_str(), "rb"); + + if(!rc_fstream[0]) + { + filename += ".cbc"; + rc_fstream[0] = SDL_RWFromFile(filename.c_str(), "rb"); + if(!rc_fstream[0]) + return false; + } + + SDL_RWread(rc_fstream[0], rc, 5, 1); + + if(! (rc[0]=='R' && rc[1] =='C' && rc[2]=='4') ) + { + string rcs = rc; + cout << "This program was not built for this version of the runtime: " << rcs << endl; + return false; + } + + //--------- type definition header ------------------- + uint64_t num_types = rcbasic_readInt(); + + rc_udtDefinition utype; + rc_udtFieldSize null_size; + + for(int i = 0; i < num_types; i++) + { + utype.num_fields = rcbasic_readInt(); + + //clear field vectors + utype.field_type.clear(); + utype.field_type_index.clear(); + utype.field_dimensions.clear(); + utype.field_size.clear(); + + for(int members = 0; members < utype.num_fields; members++) + { + utype.field_type.push_back(rcbasic_readInt()); + utype.field_type_index.push_back(rcbasic_readInt()); + utype.field_dimensions.push_back(rcbasic_readInt()); + utype.field_size.push_back(null_size); + } + + //debug + //cout << "Type #" << i << endl; + //for(int n = 0; n < utype.num_fields; n++) + // cout << " Field #" << n << ": " << utype.field_type[n] << ", " << utype.field_type_index[n] << ", " << utype.field_dimensions[n] << endl; + //cout << endl; + + rc_types.push_back(utype); + } + + // -------- end type definition header --------------- + + n_count = rcbasic_readInt(); + s_count = rcbasic_readInt(); + u_count = rcbasic_readInt(); + + n_stack_size = rcbasic_readInt(); + s_stack_size = rcbasic_readInt(); + u_stack_size = rcbasic_readInt(); + + loop_stack_size = rcbasic_readInt(); + + numID_count = rcbasic_readInt(); + strID_count = rcbasic_readInt(); + usrID_count = rcbasic_readInt(); + + code_segment_size = rcbasic_readInt(); + data_segment_size = rcbasic_readInt(); + + vm_n = new rc_vm_n[n_count]; + vm_s = new rc_vm_s[s_count]; + vm_u = new rc_usrId[u_count]; + + + num_var = new rc_numId[numID_count]; + for(int i = 0; i < numID_count; i++) + { + //num_var[i].nid_value = new n_value; + num_var[i].nid_value.value.resize(1); + num_var[i].dimensions = 0; + num_var[i].byref_offset = 0; + num_var[i].nref = &num_var[i].nid_value; + + #ifdef RCBASIC_DEBUG + num_var[i].is_debug_var = false; + #endif // RCBASIC_DEBUG + } + + str_var = new rc_strId[strID_count]; + for(int i = 0; i < strID_count; i++) + { + //str_var[i].sid_value = new s_value; + str_var[i].sid_value.value.resize(1); + str_var[i].dimensions = 0; + str_var[i].byref_offset = 0; + str_var[i].sref = &str_var[i].sid_value; + + #ifdef RCBASIC_DEBUG + str_var[i].is_debug_var = false; + #endif // RCBASIC_DEBUG + } + + //cout << "usrID_count = " << usrID_count << endl; + usr_var = new rc_usrId[usrID_count]; // this will have all of its members allocated by the dim_type instructions + + + segment = new unsigned char*[2]; + segment[CODE_SEGMENT] = new unsigned char[code_segment_size]; + segment[DATA_SEGMENT] = new unsigned char[data_segment_size]; + + SDL_RWread(rc_fstream[0], segment[CODE_SEGMENT], code_segment_size, 1); + SDL_RWread(rc_fstream[0], segment[DATA_SEGMENT], data_segment_size, 1); + + SDL_RWclose(rc_fstream[0]); + + rc_fstream[0] = NULL; + + //cout << "DEBUG: Program has been loaded" << endl; + + return true; +} + +bool rc_checkEvent() +{ + for(int i = 0; i < MAX_WINDOWS; i++) + if(rc_win[i]!=NULL) + return true; + return false; +} + +void rc_events() +{ + //rc_textinput_flag = false; + cycleVideo(); + if(rc_checkEvent()) + { + rc_fingers_pressed.clear(); + rc_inkey = 0; + rc_mouseX = -1; + rc_mouseY = -1; + rc_global_mouseX = -1; + rc_global_mouseY = -1; + rc_mwheelx = 0; + rc_mwheely = 0; + for(int i = 0; i < MAX_WINDOWS; i++) + rc_win_event[i] = 0; + while(rc_getEvents()){} + keyState = SDL_GetKeyboardState(NULL); + SDL_GetMouseState(&rc_mouseX, &rc_mouseY); + SDL_GetGlobalMouseState(&rc_global_mouseX, &rc_global_mouseY); + //rc_getEvents(); + #ifndef RC_WINDOWS + SDL_PumpEvents(); + #endif // RC_WINDOWS + //SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);// + } +} + +uint64_t readInt() +{ + for(int i = 0; i < sizeof(uint64_t); i++) + { + readint_val.data[i] = segment[current_segment][current_address]; + current_address++; + } + return readint_val.i; +} + +double readDouble() +{ + for(int i = 0; i < sizeof(double); i++) + { + readdouble_val.data[i] = segment[current_segment][current_address]; + current_address++; + } + return readdouble_val.f; +} + +void dbg_1(uint32_t dbg_fn, uint64_t arg1, uint64_t arg2) +{ + #ifdef RCBASIC_DEBUG + output_debug_message(); + + switch(dbg_fn) + { + case 0: + current_src_file = arg1; + current_src_line = arg2; + break; + } + #endif // RCBASIC_DEBUG +} + +void mov_32(int n1, int n2) +{ + vm_n[n1].value = vm_n[n2].value; +} + +void mov_33(int n1, double val) +{ + vm_n[n1].value = val; + //cout << "n" << n1 << " = " << vm_n[n1].value << endl; +} + +void mov_34(int n1, uint64_t nid) +{ + uint64_t byref_offset = num_var[nid].byref_offset; + vm_n[n1].value = num_var[nid].nref[0].value[byref_offset]; + vm_n[n1].r = num_var[nid].nref; + vm_n[n1].r_index = byref_offset; + + #ifdef RCBASIC_DEBUG + if(!num_var[nid].is_debug_var) + return; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = num_var[nid].dimensions; + tmp_stat.dim[0] = byref_offset; + tmp_stat.num_val = vm_n[n1].value; + dbg_vars[num_var[nid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG + + //cout << "n" << n1 << " = " << vm_n[n1].value << endl; +} + +void mov_35(uint64_t nid, int n1) +{ + uint64_t byref_offset = num_var[nid].byref_offset; + num_var[nid].nref[0].value[byref_offset] = vm_n[n1].value; + + #ifdef RCBASIC_DEBUG + if(!num_var[nid].is_debug_var) + return; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_SET; + tmp_stat.dimensions = num_var[nid].dimensions; + tmp_stat.dim[0] = byref_offset; + tmp_stat.num_val = vm_n[n1].value; + dbg_vars[num_var[nid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG + + //cout << "n" << n1 << " = " << vm_n[n1].value << endl; + //cout << "nvar[" << nid << "] = " << num_var[nid].nid_value[0].value[0] << endl; +} + +void movS_36(int s1, int s2) +{ + vm_s[s1].value = vm_s[s2].value; +} + +void movS_37(int s1, uint64_t str_addr) +{ + vm_s[s1].value.clear(); + char c = segment[DATA_SEGMENT][str_addr]; + uint64_t i = str_addr; + while(c != '\0') + { + vm_s[s1].value.push_back(c); + i++; + c = segment[DATA_SEGMENT][i]; + } +} + +void movS_38(int s1, uint64_t sid) +{ + uint64_t byref_offset = str_var[sid].byref_offset; + vm_s[s1].value = str_var[sid].sref[0].value[byref_offset]; + vm_s[s1].r = str_var[sid].sref; + vm_s[s1].r_index = byref_offset; + + #ifdef RCBASIC_DEBUG + if(!str_var[sid].is_debug_var) + return; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = str_var[sid].dimensions; + tmp_stat.dim[0] = byref_offset; + tmp_stat.str_val = vm_s[s1].value; + dbg_vars[str_var[sid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void movS_39(uint64_t sid, int s1) +{ + uint64_t byref_offset = str_var[sid].byref_offset; + str_var[sid].sref[0].value[byref_offset] = vm_s[s1].value; + + #ifdef RCBASIC_DEBUG + if(!str_var[sid].is_debug_var) + return; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_SET; + tmp_stat.dimensions = str_var[sid].dimensions; + tmp_stat.dim[0] = byref_offset; + tmp_stat.str_val = vm_s[s1].value; + dbg_vars[str_var[sid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void mov_r_40(int n1, int n2) +{ + vm_n[n1].r[0].value[ vm_n[n1].r_index ] = vm_n[n2].value; + + #ifdef RCBASIC_DEBUG + for(int i = 0; i < dbg_vars[vm_n[n1].dbg_var_index].usage_data.size(); i++) + { + if(dbg_vars[vm_n[n1].dbg_var_index].usage_data[i].reg==n1) + { + dbg_vars[vm_n[n1].dbg_var_index].usage_data[i].type = RCBASIC_DEBUG_ACCESS_SET; + dbg_vars[vm_n[n1].dbg_var_index].usage_data[i].str_val = vm_n[n2].value; + break; + } + } + #endif // RCBASIC_DEBUG +} + +void mov_rS_41(int s1, int s2) +{ + vm_s[s1].r[0].value[ vm_s[s1].r_index ] = vm_s[s2].value; + + #ifdef RCBASIC_DEBUG + for(int i = 0; i < dbg_vars[vm_s[s1].dbg_var_index].usage_data.size(); i++) + { + if(dbg_vars[vm_s[s1].dbg_var_index].usage_data[i].reg==s1) + { + dbg_vars[vm_s[s1].dbg_var_index].usage_data[i].type = RCBASIC_DEBUG_ACCESS_SET; + dbg_vars[vm_s[s1].dbg_var_index].usage_data[i].str_val = vm_s[s2].value; + break; + } + } + #endif // RCBASIC_DEBUG +} + +void mov_type_42(int u1, int u2) +{ + vm_u[u1].var_ref[0] = vm_u[u2]; + vm_u[u1].var_ref_index = 0; + + //if(u2 == 3) + //{ + // cout << "\nSetting value = " << vm_u[u1].var_ref[0].num_var[0].nid_value.value[0] << endl << endl; + //} +} + +void addS_43(int s1, int s2) +{ + vm_s[s1].value += vm_s[s2].value; +} + +void add_44(int n1, int n2) +{ + vm_n[n1].value += vm_n[n2].value; +} + +void sub_45(int n1, int n2) +{ + vm_n[n1].value -= vm_n[n2].value; +} + +void mul_46(int n1, int n2) +{ + vm_n[n1].value *= vm_n[n2].value; +} + +void div_47(int n1, int n2) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n2].value == 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIV_BY_ZERO; + return; + } + #endif // RCBASIC_DEBUG + vm_n[n1].value /= vm_n[n2].value; +} + +void pow_48(int n1, int n2) +{ + vm_n[n1].value = pow(vm_n[n1].value, vm_n[n2].value); +} + +void mod_49(int n1, int n2) +{ + vm_n[n1].value = (int64_t)(vm_n[n1].value) % (int64_t)(vm_n[n2].value); +} + +void shl_50(int n1, int n2) +{ + vm_n[n1].value = (int64_t)(vm_n[n1].value) << (int64_t)(vm_n[n2].value); +} + +void shr_51(int n1, int n2) +{ + vm_n[n1].value = (int64_t)(vm_n[n1].value) >> (int64_t)(vm_n[n2].value); +} + +void and_52(int n1, int n2) +{ + vm_n[n1].value = (int64_t)(vm_n[n1].value) && (int64_t)(vm_n[n2].value); +} + +void or_53(int n1, int n2) +{ + vm_n[n1].value = (int64_t)(vm_n[n1].value) || (int64_t)(vm_n[n2].value); +} + +void xor_54(int n1, int n2) +{ + vm_n[n1].value = !((int64_t)(vm_n[n1].value)) != !((int64_t)(vm_n[n2].value)); +} + +void not_55(int n1) +{ + vm_n[n1].value = !((int64_t)vm_n[n1].value); +} + +void cmp_56(int n1, int n2) +{ + CMP_FLAG_EQUAL = (vm_n[n1].value == vm_n[n2].value); + CMP_FLAG_GREATER = (vm_n[n1].value > vm_n[n2].value); + CMP_FLAG_GREATER_EQUAL = (vm_n[n1].value >= vm_n[n2].value); + CMP_FLAG_LESS = (vm_n[n1].value < vm_n[n2].value); + CMP_FLAG_LESS_EQUAL = (vm_n[n1].value <= vm_n[n2].value); + CMP_FLAG_NOT_EQUAL = (vm_n[n1].value != vm_n[n2].value); +} + +void cmpS_57(int s1, int s2) +{ + int str_cmp = vm_s[s1].value.compare(vm_s[s2].value); + CMP_FLAG_EQUAL = (str_cmp==0); + CMP_FLAG_NOT_EQUAL = (str_cmp!=0); + CMP_FLAG_GREATER = (str_cmp>0); + CMP_FLAG_GREATER_EQUAL = (CMP_FLAG_EQUAL || CMP_FLAG_GREATER); + CMP_FLAG_LESS = (str_cmp<0); + CMP_FLAG_LESS_EQUAL = (CMP_FLAG_EQUAL || CMP_FLAG_LESS); +} + +void cmp_u_58(int n1, int n2) +{ +} + +void jmp_59(int n1) +{ + current_address = (uint64_t)vm_n[n1].value; +} + +void jmp_60(uint64_t jmp_addr) +{ + current_address = jmp_addr; +} + +void je_61(int n1) +{ + if(CMP_FLAG_EQUAL) + current_address = (uint64_t)vm_n[n1].value; +} + +void je_62(uint64_t jmp_addr) +{ + if(CMP_FLAG_EQUAL) + current_address = jmp_addr; +} + +void jne_63(int n1) +{ + if(CMP_FLAG_NOT_EQUAL) + current_address = (uint64_t)vm_n[n1].value; +} + +void jne_64(uint64_t jmp_addr) +{ + if(CMP_FLAG_NOT_EQUAL) + current_address = jmp_addr; +} + +void jg_65(int n1) +{ + if(CMP_FLAG_GREATER) + current_address = (uint64_t)vm_n[n1].value; +} + +void jg_66(uint64_t jmp_addr) +{ + if(CMP_FLAG_GREATER) + current_address = jmp_addr; +} + +void jge_67(int n1) +{ + if(CMP_FLAG_GREATER_EQUAL) + current_address = (uint64_t)vm_n[n1].value; +} + +void jge_68(uint64_t jmp_addr) +{ + if(CMP_FLAG_GREATER_EQUAL) + current_address = jmp_addr; +} + +void jl_69(int n1) +{ + if(CMP_FLAG_LESS) + current_address = (uint64_t)vm_n[n1].value; +} + +void jl_70(uint64_t jmp_addr) +{ + if(CMP_FLAG_LESS) + current_address = jmp_addr; +} + +void jle_71(int n1) +{ + if(CMP_FLAG_LESS_EQUAL) + current_address = (uint64_t)vm_n[n1].value; +} + +void jle_72(uint64_t jmp_addr) +{ + if(CMP_FLAG_LESS_EQUAL) + current_address = jmp_addr; +} + +void obj_num_73(uint64_t nid) +{ + num_object.obj_val = num_var[nid].nref; + uint64_t byref_offset = num_var[nid].byref_offset; + num_object.index = byref_offset; + + #ifdef RCBASIC_DEBUG + if(!num_var[nid].is_debug_var) + return; + + uint64_t num_var_size = 1; + switch(num_var[nid].dimensions) + { + case 3: + num_var_size *= num_var[nid].dim[2]; + case 2: + num_var_size *= num_var[nid].dim[1]; + case 1: + num_var_size *= num_var[nid].dim[0]; + } + + num_object.nid = nid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = num_var[nid].dimensions; + + if(num_object.index >= num_var_size && dbg_vars[num_var[nid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_NUM) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.num_val = num_var[nid].nid_value[0].value[num_object.index]; + dbg_vars[num_var[nid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_num1_74(uint64_t nid, int n1) +{ + num_object.obj_val = num_var[nid].nref; + uint64_t byref_offset = num_var[nid].byref_offset; + num_object.index = (uint64_t)vm_n[n1].value + byref_offset; + //cout << "obj_num index = " << num_object.index << endl; + + #ifdef RCBASIC_DEBUG + if(!num_var[nid].is_debug_var) + return; + + uint64_t num_var_size = 1; + switch(num_var[nid].dimensions) + { + case 3: + num_var_size *= num_var[nid].dim[2]; + case 2: + num_var_size *= num_var[nid].dim[1]; + case 1: + num_var_size *= num_var[nid].dim[0]; + } + + num_object.nid = nid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = num_var[nid].dimensions; + tmp_stat.dim[0] = vm_n[n1].value; + + if(num_object.index >= num_var_size && dbg_vars[num_var[nid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_NUM) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.num_val = num_var[nid].nid_value[0].value[num_object.index]; + dbg_vars[num_var[nid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_num2_75(uint64_t nid, int n1, int n2) +{ + uint64_t arr_pos = (uint64_t)vm_n[n1].value * num_var[nid].dim[1] + (uint64_t)vm_n[n2].value; + num_object.obj_val = num_var[nid].nref; + uint64_t byref_offset = num_var[nid].byref_offset; + num_object.index = arr_pos + byref_offset; + + #ifdef RCBASIC_DEBUG + if(!num_var[nid].is_debug_var) + return; + + uint64_t num_var_size = 1; + switch(num_var[nid].dimensions) + { + case 3: + num_var_size *= num_var[nid].dim[2]; + case 2: + num_var_size *= num_var[nid].dim[1]; + case 1: + num_var_size *= num_var[nid].dim[0]; + } + + num_object.nid = nid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = num_var[nid].dimensions; + tmp_stat.dim[0] = vm_n[n1].value; + tmp_stat.dim[1] = vm_n[n2].value; + + if(num_object.index >= num_var_size && dbg_vars[num_var[nid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_NUM) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.num_val = num_var[nid].nid_value[0].value[num_object.index]; + dbg_vars[num_var[nid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_num3_76(uint64_t nid, int n1, int n2, int n3) +{ + uint64_t arr_pos = ( (uint64_t)vm_n[n1].value * num_var[nid].dim[1] * num_var[nid].dim[2] ) + ((uint64_t)vm_n[n2].value * num_var[nid].dim[2]) + (uint64_t)vm_n[n3].value; + num_object.obj_val = num_var[nid].nref; + uint64_t byref_offset = num_var[nid].byref_offset; + num_object.index = arr_pos + byref_offset; + + #ifdef RCBASIC_DEBUG + if(!num_var[nid].is_debug_var) + return; + + uint64_t num_var_size = 1; + switch(num_var[nid].dimensions) + { + case 3: + num_var_size *= num_var[nid].dim[2]; + case 2: + num_var_size *= num_var[nid].dim[1]; + case 1: + num_var_size *= num_var[nid].dim[0]; + } + + num_object.nid = nid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = num_var[nid].dimensions; + tmp_stat.dim[0] = vm_n[n1].value; + tmp_stat.dim[1] = vm_n[n2].value; + tmp_stat.dim[2] = vm_n[n3].value; + + if(num_object.index >= num_var_size && dbg_vars[num_var[nid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_NUM) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.num_val = num_var[nid].nid_value[0].value[num_object.index]; + dbg_vars[num_var[nid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_str_77(uint64_t sid) +{ + str_object.obj_val = str_var[sid].sref; + uint64_t byref_offset = str_var[sid].byref_offset; + str_object.index = byref_offset; + + #ifdef RCBASIC_DEBUG + if(!str_var[sid].is_debug_var) + return; + + uint64_t str_var_size = 1; + switch(str_var[sid].dimensions) + { + case 3: + str_var_size *= str_var[sid].dim[2]; + case 2: + str_var_size *= str_var[sid].dim[1]; + case 1: + str_var_size *= str_var[sid].dim[0]; + } + + str_object.sid = sid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = str_var[sid].dimensions; + tmp_stat.dim[0] = byref_offset; + if(str_object.index >= str_var_size && dbg_vars[str_var[sid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_STR) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.str_val = str_var[sid].sid_value[0].value[str_object.index]; + dbg_vars[str_var[sid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_str1_78(uint64_t sid, int n1) +{ + str_object.obj_val = str_var[sid].sref; + uint64_t byref_offset = str_var[sid].byref_offset; + str_object.index = (uint64_t)vm_n[n1].value + byref_offset; + + #ifdef RCBASIC_DEBUG + if(!str_var[sid].is_debug_var) + return; + + uint64_t str_var_size = 1; + switch(str_var[sid].dimensions) + { + case 3: + str_var_size *= str_var[sid].dim[2]; + case 2: + str_var_size *= str_var[sid].dim[1]; + case 1: + str_var_size *= str_var[sid].dim[0]; + } + str_object.sid = sid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = str_var[sid].dimensions; + tmp_stat.dim[0] = vm_n[n1].value; + if(str_object.index >= str_var_size && dbg_vars[str_var[sid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_STR) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.str_val = str_var[sid].sid_value[0].value[str_object.index]; + dbg_vars[str_var[sid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_str2_79(uint64_t sid, int n1, int n2) +{ + uint64_t arr_pos = (uint64_t)vm_n[n1].value * str_var[sid].dim[1] + (uint64_t)vm_n[n2].value; + str_object.obj_val = str_var[sid].sref; + uint64_t byref_offset = str_var[sid].byref_offset; + str_object.index = arr_pos + byref_offset; + + #ifdef RCBASIC_DEBUG + if(!str_var[sid].is_debug_var) + return; + + uint64_t str_var_size = 1; + switch(str_var[sid].dimensions) + { + case 3: + str_var_size *= str_var[sid].dim[2]; + case 2: + str_var_size *= str_var[sid].dim[1]; + case 1: + str_var_size *= str_var[sid].dim[0]; + } + + str_object.sid = sid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = str_var[sid].dimensions; + tmp_stat.dim[0] = vm_n[n1].value; + tmp_stat.dim[1] = vm_n[n2].value; + + if(str_object.index >= str_var_size && dbg_vars[str_var[sid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_STR) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.str_val = str_var[sid].sid_value[0].value[str_object.index]; + dbg_vars[str_var[sid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_str3_80(uint64_t sid, int n1, int n2, int n3) +{ + uint64_t arr_pos = ( (uint64_t)vm_n[n1].value * str_var[sid].dim[1] * str_var[sid].dim[2] ) + ((uint64_t)vm_n[n2].value * str_var[sid].dim[2]) + (uint64_t)vm_n[n3].value; + str_object.obj_val = str_var[sid].sref; + uint64_t byref_offset = str_var[sid].byref_offset; + str_object.index = arr_pos + byref_offset; + + #ifdef RCBASIC_DEBUG + if(!str_var[sid].is_debug_var) + return; + + uint64_t str_var_size = 1; + switch(str_var[sid].dimensions) + { + case 3: + str_var_size *= str_var[sid].dim[2]; + case 2: + str_var_size *= str_var[sid].dim[1]; + case 1: + str_var_size *= str_var[sid].dim[0]; + } + + str_object.sid = sid; + rcbasic_debug_access_status tmp_stat; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_GET; + tmp_stat.dimensions = str_var[sid].dimensions; + tmp_stat.dim[0] = vm_n[n1].value; + tmp_stat.dim[1] = vm_n[n2].value; + tmp_stat.dim[2] = vm_n[n3].value; + + if(str_object.index >= str_var_size && dbg_vars[str_var[sid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_STR) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + tmp_stat.is_error = true; + } + else + tmp_stat.str_val = str_var[sid].sid_value[0].value[str_object.index]; + dbg_vars[str_var[sid].dbg_var_index].usage_data.push_back(tmp_stat); + #endif // RCBASIC_DEBUG +} + +void obj_usr_81(uint64_t uid) +{ + //cout << "obj_usr " << uid << ": size = " << usr_object.obj_ref->uid_value[uid].uid_value.size() << endl; + usr_object.index = 0; + usr_object.obj_ref = &usr_object.obj_ref->uid_value[uid].uid_value[0]; +} + +void obj_usr1_82(uint64_t uid, int n1) +{ + //cout << "obj_usr1 " << uid << " " << (uint64_t)vm_n[n1].value << endl; + //cout << " ---dbg[uid]: " << usr_object.obj_ref->uid_value[uid].uid_value[1].num_var[0].nid_value.value[0] << endl; + //cout << " ---dbg[str]: " << usr_object.obj_ref->uid_value[uid].uid_value[0].str_var.size() << endl; + usr_object.index = (uint64_t)vm_n[n1].value; + usr_object.obj_ref = &usr_object.obj_ref->uid_value[uid].uid_value[usr_object.index]; +} + +void obj_usr2_83(uint64_t uid, int n1, int n2) +{ + //cout << "obj_usr2 " << uid << " " << (uint64_t)vm_n[n1].value << " " << (uint64_t)vm_n[n2].value << ": size = " << usr_object.obj_ref->uid_value.size() << endl; + usr_object.index = (uint64_t)vm_n[n1].value * usr_object.obj_ref->uid_value[uid].dim[1] + (uint64_t)vm_n[n2].value; + usr_object.obj_ref = &usr_object.obj_ref->uid_value[uid].uid_value[usr_object.index]; +} + +void obj_usr3_84(uint64_t uid, int n1, int n2, int n3) +{ + //cout << "obj_usr3 " << uid << " " << (uint64_t)vm_n[n1].value << " " << (uint64_t)vm_n[n2].value << " " << (uint64_t)vm_n[n3].value << endl; + usr_object.index = ( (uint64_t)vm_n[n1].value * usr_object.obj_ref->uid_value[uid].dim[1] * usr_object.obj_ref->uid_value[uid].dim[2] ) + ((uint64_t)vm_n[n2].value * usr_object.obj_ref->uid_value[uid].dim[2]) + (uint64_t)vm_n[n3].value;; + usr_object.obj_ref = &usr_object.obj_ref->uid_value[uid].uid_value[usr_object.index]; +} + +void obj_get_85(int n1) +{ + //cout << "var index = " << num_object.index << endl; + //cout << "store in n" << n1 << endl; + vm_n[n1].value = num_object.obj_val[0].value[num_object.index]; + //cout << "t1" << endl; + vm_n[n1].r = num_object.obj_val; + //cout << "t2" << endl; + vm_n[n1].r_index = num_object.index; + //cout << "t3" << endl; + + #ifdef RCBASIC_DEBUG + if(!num_var[num_object.nid].is_debug_var) + return; + + int usage_size = dbg_vars[num_var[num_object.nid].dbg_var_index].usage_data.size(); + dbg_vars[num_var[num_object.nid].dbg_var_index].usage_data[usage_size-1].reg = n1; + vm_n[n1].dbg_var_index = num_var[num_object.nid].dbg_var_index; + #endif // RCBASIC_DEBUG +} + +void obj_getS_86(int s1) +{ + vm_s[s1].value = str_object.obj_val[0].value[str_object.index]; + vm_s[s1].r = str_object.obj_val; + vm_s[s1].r_index = str_object.index; + + #ifdef RCBASIC_DEBUG + if(!str_var[str_object.sid].is_debug_var) + return; + + int usage_size = dbg_vars[str_var[str_object.sid].dbg_var_index].usage_data.size(); + dbg_vars[str_var[str_object.sid].dbg_var_index].usage_data[usage_size-1].reg = s1; + vm_s[s1].dbg_var_index = str_var[str_object.sid].dbg_var_index; + #endif // RCBASIC_DEBUG +} + +void obj_set_87(int n1) +{ +} + +void obj_setS_88(int s1) +{ +} + +void clear_obj_89() +{ +} + +bool rc_dim_type(rc_usrId* parent, uint64_t udt_index, int num_dim, uint64_t d1, uint64_t d2, uint64_t d3) +{ + uint64_t dim_size = 0; + switch(num_dim) + { + case 0: + dim_size = 1; + break; + case 1: + dim_size = d1; + break; + case 2: + dim_size = d1 * d2; + break; + case 3: + dim_size = d1 * d2 * d3; + break; + } + + parent->dimensions = num_dim; + parent->dim[0] = d1; + parent->dim[1] = d2; + parent->dim[2] = d3; + + parent->byref_offset = 0; + parent->uid_value.resize(dim_size); + + parent->var_ref = parent; + parent->var_ref_index = 0; + + rc_usrId* p_obj; + + uint64_t field_size = 0; + + //cout << "starting field: " << udt_index << " " << num_dim << " " << d1 << " " << d2 << " " << d3 << ": " << parent->uid_value.size() << endl; + + for(uint64_t i = 0; i < dim_size; i++) + { + p_obj = &parent->uid_value[i]; + + for(int field = 0; field < rc_types[udt_index].num_fields; field++) + { + field_size = 1; + switch(rc_types[udt_index].field_dimensions[field]) + { + case 3: + field_size *= rc_types[udt_index].field_size[field].dim[2]; + case 2: + field_size *= rc_types[udt_index].field_size[field].dim[1]; + case 1: + field_size *= rc_types[udt_index].field_size[field].dim[0]; + break; + } + + switch(rc_types[udt_index].field_type[field]) + { + case RC_UDT_TYPE_NUM: + { + rc_numId tmp_num_var; + //tmp_num_var.nid_value = new n_value; + tmp_num_var.nid_value.value.resize(field_size); + tmp_num_var.dimensions = rc_types[udt_index].field_dimensions[field]; + tmp_num_var.dim[0] = rc_types[udt_index].field_size[field].dim[0]; + tmp_num_var.dim[1] = rc_types[udt_index].field_size[field].dim[1]; + tmp_num_var.dim[2] = rc_types[udt_index].field_size[field].dim[2]; + p_obj->num_var.push_back(tmp_num_var); + uint64_t nv_index = p_obj->num_var.size()-1; + p_obj->num_var[nv_index].nref = &p_obj->num_var[nv_index].nid_value; + } + break; + case RC_UDT_TYPE_STR: + { + rc_strId tmp_str_var; + //tmp_str_var.sid_value = new s_value; + tmp_str_var.sid_value.value.resize(field_size); + tmp_str_var.dimensions = rc_types[udt_index].field_dimensions[field]; + tmp_str_var.dim[0] = rc_types[udt_index].field_size[field].dim[0]; + tmp_str_var.dim[1] = rc_types[udt_index].field_size[field].dim[1]; + tmp_str_var.dim[2] = rc_types[udt_index].field_size[field].dim[2]; + p_obj->str_var.push_back(tmp_str_var); + uint64_t sv_index = p_obj->str_var.size()-1; + p_obj->str_var[sv_index].sref = &p_obj->str_var[sv_index].sid_value; + } + break; + case RC_UDT_TYPE_USR: + { + //WIP: p_obj is just going to get resized everytime this is called. So instead I need to create a type object to add and run rc_dim_type on that + rc_usrId usr_field; + rc_dim_type(&usr_field, rc_types[udt_index].field_type_index[field], rc_types[udt_index].field_dimensions[field], + rc_types[udt_index].field_size[field].dim[0], + rc_types[udt_index].field_size[field].dim[1], + rc_types[udt_index].field_size[field].dim[2]); + p_obj->uid_value.push_back(usr_field); + } + break; + } + } + } + return true; +} + +bool rc_free_type(rc_usrId* parent) +{ + uint64_t dim_size = parent->uid_value.size(); + + + rc_usrId* p_obj; + + uint64_t field_size = 0; + + for(uint64_t i = 0; i < dim_size; i++) + { + p_obj = &parent->uid_value[i]; + + for(uint64_t n_field = 0; n_field < p_obj->num_var.size(); n_field++) + { + p_obj->num_var[n_field].nid_value.value.clear(); + p_obj->num_var[n_field].nid_value.value.shrink_to_fit(); + //delete p_obj->num_var[n_field].nid_value; + } + + for(uint64_t s_field = 0; s_field < p_obj->str_var.size(); s_field++) + { + p_obj->str_var[s_field].sid_value.value.clear(); + p_obj->str_var[s_field].sid_value.value.shrink_to_fit(); + //delete p_obj->str_var[s_field].sid_value; + } + + for(uint64_t u_field = 0; u_field < p_obj->uid_value.size(); u_field++) + { + rc_free_type(&p_obj->uid_value[u_field]); + p_obj->uid_value[u_field].uid_value.clear(); + p_obj->uid_value[u_field].uid_value.shrink_to_fit(); + } + } + + parent->uid_value.clear(); + parent->uid_value.shrink_to_fit(); + + return true; +} + +void dim_type_90(uint64_t uid, uint64_t udt_index) +{ + //cout << "DimType " << uid << " " << udt_index << endl; + rc_free_type(&usr_var[uid]); + //cout << "Freed memory" << endl; + rc_dim_type( &usr_var[uid], udt_index, 0, 0, 0, 0 ); + //cout << "DimType End" << endl; +} + +void dim_type1_91(uint64_t uid, uint64_t udt_index, int n1) +{ + //cout << "DimType1 " << uid << " " << udt_index << " " << (uint64_t)vm_n[n1].value << endl; + rc_free_type(&usr_var[uid]); + rc_dim_type( &usr_var[uid], udt_index, 1, (uint64_t)vm_n[n1].value, 0, 0 ); + //cout << "DimType End" << endl; +} + +void dim_type2_92(uint64_t uid, uint64_t udt_index, int n1, int n2) +{ + //cout << "DimType2 " << uid << " " << udt_index << " " << (uint64_t)vm_n[n1].value << " " << (uint64_t)vm_n[n2].value << endl; + rc_free_type(&usr_var[uid]); + rc_dim_type( &usr_var[uid], udt_index, 2, (uint64_t)vm_n[n1].value, (uint64_t)vm_n[n2].value, 0 ); + //cout << "DimType End" << endl; +} + +void dim_type3_93(uint64_t uid, uint64_t udt_index, int n1, int n2, int n3) +{ + //cout << "DimType3 " << uid << " " << udt_index << " " << (uint64_t)vm_n[n1].value << " " << (uint64_t)vm_n[n2].value << " " << (uint64_t)vm_n[n3].value << endl; + rc_free_type(&usr_var[uid]); + rc_dim_type( &usr_var[uid], udt_index, 3, (uint64_t)vm_n[n1].value, (uint64_t)vm_n[n2].value, (uint64_t)vm_n[n3].value ); + //cout << "DimType End" << endl; +} + +void dim_num1_94(uint64_t nid, int n1) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + num_var[nid].nid_value.value.resize((uint64_t)vm_n[n1].value); + num_var[nid].nref = &num_var[nid].nid_value; + num_var[nid].dimensions = 1; + num_var[nid].dim[0] = (uint64_t)vm_n[n1].value; + num_var[nid].dim[1] = 0; + num_var[nid].dim[2] = 0; +} + +void dim_num2_95(uint64_t nid, int n1, int n2) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + num_var[nid].nid_value.value.resize((uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value); + num_var[nid].nref = &num_var[nid].nid_value; + num_var[nid].dimensions = 2; + num_var[nid].dim[0] = (uint64_t)vm_n[n1].value; + num_var[nid].dim[1] = (uint64_t)vm_n[n2].value; + num_var[nid].dim[2] = 0; +} + +void dim_num3_96(uint64_t nid, int n1, int n2, int n3) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0 || vm_n[n3].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + num_var[nid].nid_value.value.resize((uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value * (uint64_t)vm_n[n3].value); + num_var[nid].nref = &num_var[nid].nid_value; + num_var[nid].dimensions = 3; + num_var[nid].dim[0] = (uint64_t)vm_n[n1].value; + num_var[nid].dim[1] = (uint64_t)vm_n[n2].value; + num_var[nid].dim[2] = (uint64_t)vm_n[n3].value; +} + +void dim_str1_97(uint64_t sid, int n1) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + str_var[sid].sid_value.value.resize((uint64_t)vm_n[n1].value); + str_var[sid].sref = &str_var[sid].sid_value; + str_var[sid].dimensions = 1; + str_var[sid].dim[0] = (uint64_t)vm_n[n1].value; + str_var[sid].dim[1] = 0; + str_var[sid].dim[2] = 0; +} + +void dim_str2_98(uint64_t sid, int n1, int n2) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + str_var[sid].sid_value.value.resize((uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value); + str_var[sid].sref = &str_var[sid].sid_value; + str_var[sid].dimensions = 2; + str_var[sid].dim[0] = (uint64_t)vm_n[n1].value; + str_var[sid].dim[1] = (uint64_t)vm_n[n2].value; + str_var[sid].dim[2] = 0; +} + +void dim_str3_99(uint64_t sid, int n1, int n2, int n3) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0 || vm_n[n3].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_DIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + str_var[sid].sid_value.value.resize((uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value * (uint64_t)vm_n[n3].value); + str_var[sid].sref = &str_var[sid].sid_value; + str_var[sid].dimensions = 3; + str_var[sid].dim[0] = (uint64_t)vm_n[n1].value; + str_var[sid].dim[1] = (uint64_t)vm_n[n2].value; + str_var[sid].dim[2] = (uint64_t)vm_n[n3].value; +} + +void delete_100(uint64_t nid) +{ + num_var[nid].nid_value.value.clear(); + num_var[nid].nid_value.value.shrink_to_fit(); + num_var[nid].dimensions = 0; + num_var[nid].dim[0] = 0; + num_var[nid].dim[1] = 0; + num_var[nid].dim[2] = 0; +} + +void deleteS_101(uint64_t sid) +{ + str_var[sid].sid_value.value.clear(); + str_var[sid].sid_value.value.shrink_to_fit(); + str_var[sid].dimensions = 0; + str_var[sid].dim[0] = 0; + str_var[sid].dim[1] = 0; + str_var[sid].dim[2] = 0; +} + +void push_102(int n1) +{ + //n_stack[current_n_stack_count] = vm_n[n1].value; + //current_n_stack_count++; + n_stack.push(vm_n[n1]); +} + +void push_103(uint64_t nid) +{ + //n_stack[current_n_stack_count] = num_var[nid].value[0]; + //current_n_stack_count++; + rc_vm_n n; + uint64_t byref_offset = num_var[nid].byref_offset; + n.value = num_var[nid].nref[0].value[byref_offset]; + n.r_index = byref_offset; + n_stack.push(n); +} + +void pushS_104(int s1) +{ + //s_stack[current_s_stack_count] = vm_s[s1].value; + //current_s_stack_count++; + s_stack.push(vm_s[s1]); +} + +void pushS_105(uint64_t sid) +{ + //s_stack[current_s_stack_count] = str_var[sid].value[0]; + //current_s_stack_count++; + rc_vm_s s; + uint64_t byref_offset = str_var[sid].byref_offset; + s.value = str_var[sid].sref[0].value[byref_offset]; + s.r_index = byref_offset; + s_stack.push(s); +} + +void push_emptyS_106() +{ + rc_vm_s s_empty; + s_empty.value = ""; + //s_stack[current_s_stack_count] = ""; + //current_s_stack_count++; + s_stack.push(s_empty); +} + +void pop_107(int n1) +{ + //current_n_stack_count--; + //vm_n[n1].value = n_stack[current_n_stack_count]; + vm_n[n1].value = n_stack.top().value; + vm_n[n1].r = n_stack.top().r; + vm_n[n1].r_index = n_stack.top().r_index; + n_stack.pop(); +} + +void pop_108(uint64_t nid) +{ + //current_n_stack_count--; + //num_var[nid].value[0] = n_stack[current_n_stack_count]; + uint64_t byref_offset = n_stack.top().r_index; + num_var[nid].nref[0].value[byref_offset] = n_stack.top().value; + num_var[nid].byref_offset = byref_offset; + n_stack.pop(); +} + +void popS_109(int s1) +{ + //current_s_stack_count--; + //vm_s[s1].value = s_stack[current_s_stack_count]; + vm_s[s1].value = s_stack.top().value; + vm_s[s1].r = s_stack.top().r; + vm_s[s1].r_index = s_stack.top().r_index; + s_stack.pop(); +} + +void popS_110(uint64_t sid) +{ + //current_s_stack_count--; + //str_var[sid].value[0] = s_stack[current_s_stack_count]; + uint64_t byref_offset = s_stack.top().r_index; + str_var[sid].sref[0].value[byref_offset] = s_stack.top().value; + str_var[sid].byref_offset = byref_offset; + s_stack.pop(); +} + +void get_stack_size_111(int n1) +{ + vm_n[n1].value = n_stack.size(); +} + +void get_stack_sizeS_112(int n1) +{ + vm_n[n1].value = s_stack.size(); +} + +void clear_stack_113() +{ + //current_n_stack_count = 0; + n_stack.empty(); +} + +void clear_stackS_114() +{ + //current_s_stack_count = 0; + s_stack.empty(); +} + +void while_115(int n1, uint64_t jmp_addr) +{ + if(vm_n[n1].value == 0) + current_address = jmp_addr; + //rc_events(); +} + +void wend_116(uint64_t jmp_addr) +{ + current_address = jmp_addr; +} + +void for_117(uint64_t nid, int n1, int n2, int n3) +{ + rc_loop for_loop; + for_loop.counter = &num_var[nid]; + for_loop.f_end = vm_n[n2].value; + for_loop.f_step = vm_n[n3].value; + + switch(for_offset_dimensions) + { + case 1: + for_loop.counter_offset = for_offset_index[0]; + break; + case 2: + for_loop.counter_offset = for_offset_index[0] * num_var[nid].dim[1] + for_offset_index[1]; + break; + case 3: + for_loop.counter_offset = ( for_offset_index[0] * num_var[nid].dim[1] * num_var[nid].dim[2] ) + (for_offset_index[1] * num_var[nid].dim[2]) + for_offset_index[2]; + break; + default: + for_loop.counter_offset = 0; + } + + uint64_t byref_offset = num_var[nid].byref_offset; + + #ifdef RCBASIC_DEBUG + uint64_t nv_size = 1; + uint64_t dbg_index = num_var[nid].dbg_var_index; + rcbasic_debug_access_status tmp_stat; + for_loop.counter_dim[0] = for_offset_index[0]; + for_loop.counter_dim[1] = for_offset_index[1]; + for_loop.counter_dim[2] = for_offset_index[2]; + + switch(num_var[nid].dimensions) + { + case 3: nv_size *= num_var[nid].dim[2]; + case 2: nv_size *= num_var[nid].dim[1]; + case 1: nv_size *= num_var[nid].dim[0]; + break; + } + + if(num_var[nid].is_debug_var) + { + tmp_stat.dimensions = num_var[nid].dimensions; + tmp_stat.dim[0] = for_offset_index[0]; + tmp_stat.dim[1] = for_offset_index[1]; + tmp_stat.dim[2] = for_offset_index[2]; + tmp_stat.num_val = vm_n[n1].value; + tmp_stat.reg = -1; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_SET; + } + + if((byref_offset + for_loop.counter_offset) >= nv_size && num_var[nid].is_debug_var) + { + if(dbg_vars[num_var[nid].dbg_var_index].type != RCBASIC_DEBUG_VAR_BYREF_NUM) + { + dbg_error_found = true; + dbg_error_message = DBG_INDEX_EXCEEDS_SIZE; + + if(num_var[nid].is_debug_var) + tmp_stat.is_error = true; + + dbg_vars[dbg_index].usage_data.push_back(tmp_stat); + + return; + } + } + else + { + dbg_vars[dbg_index].usage_data.push_back(tmp_stat); + } + #endif // RCBASIC_DEBUG + + num_var[nid].nref[0].value[byref_offset + for_loop.counter_offset] = vm_n[n1].value; + + + //These 3 lines reads the line value passed by the compiler + //This line value is the address of the end of the loop + unsigned rcbasic_cmd = segment[current_segment][current_address]; + current_address++; + uint64_t for_end_addr = readInt(); + + //cout << "next_addr: " << next_addr << endl; + + if( vm_n[n2].value < vm_n[n1].value ) + { + for_loop.isNegative = true; + + if(for_loop.f_step > 0) + { + current_address = for_end_addr; + return; + } + } + else + { + for_loop.isNegative = false; + + if(for_loop.f_step < 0) + { + current_address = for_end_addr; + return; + } + } + + + loop_stack.push(for_loop); + //current_loop_stack_count++; + //cout << "nid = " << nid << " --> " << (uint64_t)(&num_var[nid].nid_value[0].value[0]) << endl; + //cout << "nid_value = " << num_var[nid].nid_value[0].value[0] << endl; + //cout << "id[10] = " << num_var[10].nid_value[0].value[0] << " --> " << (uint64_t)(&num_var[10].nid_value[0].value[0]) << endl; + //cout << "id[11] = " << num_var[11].nid_value[0].value[0] << " --> " << (uint64_t)(&num_var[11].nid_value[0].value[0]) << endl; + //cin.get(); +} + +void next_118(uint64_t f_addr) +{ + //int l_index = current_loop_stack_count-1; + uint64_t byref_offset = loop_stack.top().counter[0].byref_offset + loop_stack.top().counter_offset; + double next_step = loop_stack.top().counter[0].nref[0].value[byref_offset] + loop_stack.top().f_step; + if(loop_stack.top().isNegative && next_step <= loop_stack.top().counter[0].nref[0].value[byref_offset] && next_step >= loop_stack.top().f_end) + { + loop_stack.top().counter[0].nref[0].value[byref_offset] += loop_stack.top().f_step; + current_address = f_addr; + + #ifdef RCBASIC_DEBUG + if(loop_stack.top().counter[0].is_debug_var) + { + rcbasic_debug_access_status tmp_stat; + tmp_stat.dimensions = loop_stack.top().counter[0].dimensions; + tmp_stat.dim[0] = loop_stack.top().counter_dim[0]; + tmp_stat.dim[1] = loop_stack.top().counter_dim[1]; + tmp_stat.dim[2] = loop_stack.top().counter_dim[2]; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_SET; + tmp_stat.num_val = loop_stack.top().counter[0].nid_value[0].value[byref_offset]; + dbg_vars[loop_stack.top().counter[0].dbg_var_index].usage_data.push_back(tmp_stat); + } + #endif // RCBASIC_DEBUG + } + else if( (!loop_stack.top().isNegative) && next_step >= loop_stack.top().counter[0].nref[0].value[byref_offset] && next_step <= loop_stack.top().f_end) + { + loop_stack.top().counter[0].nref[0].value[byref_offset] += loop_stack.top().f_step; + current_address = f_addr; + + #ifdef RCBASIC_DEBUG + if(loop_stack.top().counter[0].is_debug_var) + { + rcbasic_debug_access_status tmp_stat; + tmp_stat.dimensions = loop_stack.top().counter[0].dimensions; + tmp_stat.dim[0] = loop_stack.top().counter_dim[0]; + tmp_stat.dim[1] = loop_stack.top().counter_dim[1]; + tmp_stat.dim[2] = loop_stack.top().counter_dim[2]; + tmp_stat.type = RCBASIC_DEBUG_ACCESS_SET; + tmp_stat.num_val = loop_stack.top().counter[0].nid_value[0].value[byref_offset]; + dbg_vars[loop_stack.top().counter[0].dbg_var_index].usage_data.push_back(tmp_stat); + } + #endif // RCBASIC_DEBUG + } + else + { + loop_stack.pop(); + //current_loop_stack_count--; + } + //cout << "id[10] = " << num_var[10].nid_value[0].value[0] << " --> " << (uint64_t)(&num_var[10].nid_value[0].value[0]) << endl; + //cout << "id[11] = " << num_var[11].nid_value[0].value[0] << " --> " << (uint64_t)(&num_var[11].nid_value[0].value[0]) << endl; + //cin.get(); + //there is no point in trying to poll events in a for loop so i disabled it + //rc_events(); +} + +void do_119() //I realized that I didn't need this so its here so I can keep numbered order from my initial design +{ +} + +void loop_120(uint64_t jmp_addr) //not actually used +{ + current_address = jmp_addr; + //rc_events(); +} + +void loop_while_121(int n1, uint64_t jmp_addr) +{ + if(vm_n[n1].value != 0) + current_address = jmp_addr; + //rc_events(); +} + +void loop_until_122(int n1, uint64_t jmp_addr) +{ + if(vm_n[n1].value == 0) + current_address = jmp_addr; + //rc_events(); +} + +void pop_loop_stack_123() +{ + loop_stack.pop(); +} + +void gosub_124(uint64_t sub_addr) +{ + //cout << "gosub" << endl; + gosub_return_addr.push(current_segment); + gosub_return_addr.push(current_address); + current_segment = DATA_SEGMENT; + current_address = sub_addr; + //cout << "sub: " << sub_addr << endl; +} + +void return_125() +{ + //cout << "\nvar 0 = " << num_var[0].value[0] << endl; + //cout << "var1 = " << num_var[1].value[0] << endl; + //cout << "current address = " << current_segment << " : " << current_address << endl; + current_address = gosub_return_addr.top(); + gosub_return_addr.pop(); + current_segment = gosub_return_addr.top(); + gosub_return_addr.pop(); + //cout << "return to: " << current_segment << " : " << current_address << endl; +} + +addr_entry byref_id; + +#define BYREF_TYPE_NUM 0 +#define BYREF_TYPE_STR 1 +#define BYREF_TYPE_USR 2 + +void ptr_126(uint64_t nid, int n1) +{ + byref_id.ptr_id = nid; + byref_id.ptr_addr = num_var[nid].nref; + byref_id.type = BYREF_TYPE_NUM; + byref_addr_table.push(byref_id); + byref_var_byref_offset.push(num_var[nid].byref_offset); + num_var[nid].nref = vm_n[n1].r; + num_var[nid].byref_offset = vm_n[n1].r_index; +} + +void ptrS_127(uint64_t sid, int s1) +{ + byref_id.ptr_id = sid; + byref_id.ptr_addr = str_var[sid].sref; + byref_id.type = BYREF_TYPE_STR; + byref_addr_table.push(byref_id); + byref_var_byref_offset.push(str_var[sid].byref_offset); + str_var[sid].sref = vm_s[s1].r; + str_var[sid].byref_offset = vm_s[s1].r_index; +} + +void rc_print_num(double n) +{ + stringstream s; + s << fixed << n; + string s_out = s.str(); + int s_decimal = s_out.find_first_of("."); + if(s_decimal != string::npos) + { + int trail_end = s_out.length(); + for(int i = s_decimal; i < s_out.length(); i++) + { + if(s_out[i] != '0') + trail_end = i+1; + } + s_out = s_out.substr(0, trail_end); + if(s_out.substr(s_out.length()-1,1).compare(".")==0) + s_out = s_out.substr(0, s_out.length()-1); + } + cout << s_out; +} + +void print_128(int n1) +{ + rc_print_num(vm_n[n1].value); +} + +void printS_129(int s1) +{ + cout << vm_s[s1].value; +} + +void rc_push_num(double n_val) +{ + rc_vm_n n; + n.value = n_val; + n_stack.push(n); + //current_n_stack_count++; +} + +void rc_push_str(string s_val) +{ + rc_vm_s s; + s.value = s_val; + s_stack.push(s); + //current_s_stack_count++; +} + +uint64_t rc_string_array_dim(rc_strId s_var) +{ + return s_var.dimensions; +} + +uint64_t rc_string_array_size(rc_strId s_var, int d_num) +{ + switch(d_num) + { + case 1: + return s_var.dim[0]; + break; + case 2: + return s_var.dim[1]; + break; + case 3: + return s_var.dim[2]; + break; + } + return 0; +} + +uint64_t rc_number_array_dim(rc_numId n_var) +{ + return n_var.dimensions; +} + +uint64_t rc_number_array_size(rc_numId n_var, int d_num) +{ + switch(d_num) + { + case 1: + return n_var.dim[0]; + break; + case 2: + return n_var.dim[1]; + break; + case 3: + return n_var.dim[2]; + break; + } + return 0; +} + +void rc_number_array_copy(uint64_t src_ref_id, uint64_t dst_ref_id) +{ + uint64_t src_dim, src_dim_size[3]; + src_dim = rc_number_array_dim( num_var[src_ref_id] ); + src_dim_size[0] = rc_number_array_size( num_var[src_ref_id], 1); + src_dim_size[1] = rc_number_array_size( num_var[src_ref_id], 2); + src_dim_size[2] = rc_number_array_size( num_var[src_ref_id], 3); + + uint64_t total_size = 0; + + switch(src_dim) + { + case 1: + total_size = src_dim_size[0]; + num_var[dst_ref_id].nref[0].value.resize(total_size); + num_var[dst_ref_id].dimensions = 1; + num_var[dst_ref_id].dim[0] = src_dim_size[0]; + num_var[dst_ref_id].dim[1] = 0; + num_var[dst_ref_id].dim[2] = 0; + break; + case 2: + total_size = src_dim_size[0] * src_dim_size[1]; + num_var[dst_ref_id].nref[0].value.resize(total_size); + num_var[dst_ref_id].dimensions = 2; + num_var[dst_ref_id].dim[0] = src_dim_size[0]; + num_var[dst_ref_id].dim[1] = src_dim_size[1]; + num_var[dst_ref_id].dim[2] = 0; + break; + case 3: + total_size = src_dim_size[0] * src_dim_size[1] * src_dim_size[2]; + num_var[dst_ref_id].nref[0].value.resize(total_size); + num_var[dst_ref_id].dimensions = 3; + num_var[dst_ref_id].dim[0] = src_dim_size[0]; + num_var[dst_ref_id].dim[1] = src_dim_size[1]; + num_var[dst_ref_id].dim[2] = src_dim_size[2]; + break; + } + + for(int i = 0; i < total_size; i++) + { + num_var[dst_ref_id].nref[0].value[i] = num_var[src_ref_id].nref[0].value[i]; + } +} + +void rc_string_array_copy(uint64_t src_ref_id, uint64_t dst_ref_id) +{ + uint64_t src_dim, src_dim_size[3]; + src_dim = rc_string_array_dim( str_var[src_ref_id] ); + src_dim_size[0] = rc_string_array_size( str_var[src_ref_id], 1); + src_dim_size[1] = rc_string_array_size( str_var[src_ref_id], 2); + src_dim_size[2] = rc_string_array_size( str_var[src_ref_id], 3); + + uint64_t total_size = 0; + + switch(src_dim) + { + case 1: + total_size = src_dim_size[0]; + str_var[dst_ref_id].sref[0].value.resize(total_size); + str_var[dst_ref_id].dimensions = 1; + str_var[dst_ref_id].dim[0] = src_dim_size[0]; + str_var[dst_ref_id].dim[1] = 0; + str_var[dst_ref_id].dim[2] = 0; + break; + case 2: + total_size = src_dim_size[0] * src_dim_size[1]; + str_var[dst_ref_id].sref[0].value.resize(total_size); + str_var[dst_ref_id].dimensions = 2; + str_var[dst_ref_id].dim[0] = src_dim_size[0]; + str_var[dst_ref_id].dim[1] = src_dim_size[1]; + str_var[dst_ref_id].dim[2] = 0; + break; + case 3: + total_size = src_dim_size[0] * src_dim_size[1] * src_dim_size[2]; + str_var[dst_ref_id].sref[0].value.resize(total_size); + str_var[dst_ref_id].dimensions = 3; + str_var[dst_ref_id].dim[0] = src_dim_size[0]; + str_var[dst_ref_id].dim[1] = src_dim_size[1]; + str_var[dst_ref_id].dim[2] = src_dim_size[2]; + break; + } + + for(int i = 0; i < total_size; i++) + { + str_var[dst_ref_id].sref[0].value[i] = str_var[src_ref_id].sref[0].value[i]; + } +} + +void rc_number_array_fill(uint64_t src_ref_id, double n) +{ + uint64_t src_dim, src_dim_size[3]; + src_dim = rc_number_array_dim( num_var[src_ref_id] ); + src_dim_size[0] = rc_number_array_size( num_var[src_ref_id], 1); + src_dim_size[1] = rc_number_array_size( num_var[src_ref_id], 2); + src_dim_size[2] = rc_number_array_size( num_var[src_ref_id], 3); + + uint64_t total_size = 0; + + switch(src_dim) + { + case 1: + total_size = src_dim_size[0]; + break; + case 2: + total_size = src_dim_size[0] * src_dim_size[1]; + break; + case 3: + total_size = src_dim_size[0] * src_dim_size[1] * src_dim_size[2]; + break; + } + + for(int i = 0; i < total_size; i++) + { + num_var[src_ref_id].nref[0].value[i] = n; + } +} + +void rc_string_array_fill(uint64_t src_ref_id, string s) +{ + uint64_t src_dim, src_dim_size[3]; + src_dim = rc_string_array_dim( str_var[src_ref_id] ); + src_dim_size[0] = rc_string_array_size( str_var[src_ref_id], 1); + src_dim_size[1] = rc_string_array_size( str_var[src_ref_id], 2); + src_dim_size[2] = rc_string_array_size( str_var[src_ref_id], 3); + + uint64_t total_size = 0; + + switch(src_dim) + { + case 1: + total_size = src_dim_size[0]; + break; + case 2: + total_size = src_dim_size[0] * src_dim_size[1]; + break; + case 3: + total_size = src_dim_size[0] * src_dim_size[1] * src_dim_size[2]; + break; + } + + for(int i = 0; i < total_size; i++) + { + str_var[src_ref_id].sref[0].value[i] = s; + } +} + +void func_130(uint64_t fn) +{ + //need to setup a switch statement for all buitlin fucntions here + switch(fn) + { + case FN_FPrint: + //cout << "gosub addr size: " << gosub_return_addr.size() << endl; + //cout << "for stack size: " << loop_stack.size() << endl; + //cout << "byref addr table: " << byref_addr_table.size() << endl << endl; + rc_fprint( FPRINT_TXT$ ); + break; + case FN_Input$: + rc_push_str( rc_input(INPUT$_PROMPT$) ); + break; + case FN_StringArrayDim: + rc_push_num( rc_string_array_dim( str_var[arr_ref_id[0]] ) ); + arr_ref_id.clear(); + break; + case FN_NumberArrayDim: + rc_push_num( rc_number_array_dim( num_var[arr_ref_id[0]] ) ); + arr_ref_id.clear(); + break; + case FN_StringArraySize: + rc_push_num( rc_string_array_size( str_var[arr_ref_id[0]], STRINGARRAYSIZE_ARRAY_DIM)); + arr_ref_id.clear(); + break; + case FN_NumberArraySize: + rc_push_num( rc_number_array_size( num_var[arr_ref_id[0]], NUMBERARRAYSIZE_ARRAY_DIM)); + arr_ref_id.clear(); + break; + case FN_Abs: + rc_push_num( rc_intern_abs( ABS_N ) ); + break; + case FN_ACos: + rc_push_num( rc_intern_aCos( ACOS_N ) ); + break; + case FN_AndBit: + rc_push_num( rc_intern_andBit( ANDBIT_A, ANDBIT_B ) ); + break; + case FN_ASin: + rc_push_num( rc_intern_aSin( ASIN_N ) ); + break; + case FN_ATan: + rc_push_num( rc_intern_aTan( ATAN_N ) ); + break; + case FN_Bin$: + rc_push_str( rc_intern_bin( BIN$_N ) ); + break; + case FN_CInt32: + rc_push_num( rc_intern_cint32( CINT32_I )); + break; + case FN_CInt64: + rc_push_num( rc_intern_cint64( CINT64_I )); + break; + case FN_Cos: + rc_push_num( rc_intern_cos( COS_N ) ); + break; + case FN_Degrees: + rc_push_num( rc_intern_degrees(DEGREES_R)); + break; + case FN_Exp: + rc_push_num( rc_intern_exp( EXP_N ) ); + break; + case FN_Frac: + rc_push_num( rc_intern_frac( FRAC_N ) ); + break; + case FN_Hex$: + rc_push_str( rc_intern_hex( HEX$_N ) ); + break; + case FN_HexVal: + rc_push_num( rc_intern_hexInt( HEXVAL_N$ ) ); + break; + case FN_Int: + rc_push_num( rc_intern_int( INT_N ) ); + break; + case FN_Log: + rc_push_num( rc_intern_log( LOG_N ) ); + break; + case FN_Max: + rc_push_num( rc_intern_max( MAX_A, MAX_B ) ); + break; + case FN_Min: + rc_push_num( rc_intern_min( MIN_A, MIN_B ) ); + break; + case FN_OrBit: + rc_push_num( rc_intern_orBit( ORBIT_A, ORBIT_B ) ); + break; + case FN_Radians: + rc_push_num( rc_intern_radians(RADIANS_D)); + break; + case FN_Randomize: + rc_push_num( rc_intern_randomize( RANDOMIZE_N ) ); + break; + case FN_Rand: + rc_push_num( rc_intern_rand( RAND_N ) ); + break; + case FN_Round: + rc_push_num( rc_intern_round( ROUND_N ) ); + break; + case FN_Sign: + rc_push_num( rc_intern_sign( SIGN_N ) ); + break; + case FN_Sin: + rc_push_num( rc_intern_sin( SIN_N ) ); + break; + case FN_Sqrt: + rc_push_num( rc_intern_sqrt( SQRT_N ) ); + break; + case FN_Tan: + rc_push_num( rc_intern_tan( TAN_N ) ); + break; + case FN_XOrBit: + rc_push_num( rc_intern_xorbit( XORBIT_A, XORBIT_B ) ); + break; + case FN_Asc: + rc_push_num( rc_intern_asc( ASC_C$ ) ); + break; + case FN_Chr$: + rc_push_str( rc_intern_chr( CHR$_N ) ); + break; + case FN_Insert$: + rc_push_str( rc_intern_insert( INSERT$_SRC$, INSERT$_TGT$, INSERT$_POS ) ); + break; + case FN_InStr: + rc_push_num( rc_intern_instr( INSTR_SRC$, INSTR_SUBSTR$ ) ); + break; + case FN_LCase$: + rc_push_str( rc_intern_lcase( LCASE$_SRC$ ) ); + break; + case FN_Left$: + rc_push_str( rc_intern_left( LEFT$_SRC$, LEFT$_N ) ); + break; + case FN_Len: + rc_push_num( rc_intern_length( LEN_SRC$ ) ); + break; + case FN_Length: + rc_push_num( rc_intern_length( LENGTH_SRC$ ) ); + break; + case FN_LTrim$: + rc_push_str( rc_intern_ltrim( LTRIM$_SRC$ ) ); + break; + case FN_Mid$: + rc_push_str( rc_intern_mid( MID$_SRC$, MID$_START, MID$_N ) ); + break; + case FN_ReplaceSubstr$: + rc_push_str( rc_intern_replaceSubstr( REPLACESUBSTR$_SRC$, REPLACESUBSTR$_RPC$, REPLACESUBSTR$_POS) ); + break; + case FN_Replace$: + rc_push_str( rc_intern_replace( REPLACE$_SRC$, REPLACE$_TGT$, REPLACE$_RPC$ ) ); + break; + case FN_Reverse$: + rc_push_str( rc_intern_reverse( REVERSE$_SRC$ ) ); + break; + case FN_Right$: + rc_push_str( rc_intern_right( RIGHT$_SRC$, RIGHT$_N ) ); + break; + case FN_RTrim$: + rc_push_str( rc_intern_rtrim( RTRIM$_SRC$ ) ); + break; + case FN_StringFill$: + rc_push_str( rc_intern_stringfill( STRINGFILL$_SRC$, STRINGFILL$_N ) ); + break; + case FN_Str$: + rc_push_str( rc_intern_str( STR$_N ) ); + break; + case FN_Str_F$: + rc_push_str( rc_intern_str_f( STR_F$_N ) ); + break; + case FN_Str_S$: + rc_push_str( rc_intern_str_s( STR_S$_N ) ); + break; + case FN_Tally: + rc_push_num( rc_intern_tally( TALLY_SRC$, TALLY_SUBSTR$ ) ); + break; + case FN_Trim$: + rc_push_str( rc_intern_trim( TRIM$_SRC$ ) ); + break; + case FN_UCase$: + rc_push_str( rc_intern_ucase( UCASE$_SRC$ ) ); + break; + case FN_Val: + rc_push_num( rc_intern_val( VAL_N$ ) ); + break; + case FN_Stack_N: //Sub Procedure + if(STACK_N_N >= 0 && STACK_N_N <= (MAX_USER_STACKS-1)) + rc_user_active_n_stack = STACK_N_N; + else + cout << "Stack_N Error: Exceeds available stacks" << endl; + break; + case FN_Stack_S: //Sub Procedure + if(STACK_S_N >= 0 && STACK_S_N <= (MAX_USER_STACKS-1)) + rc_user_active_s_stack = STACK_S_N; + else + cout << "Stack_S Error: Exceeds available stacks" << endl; + break; + case FN_Push_N: + rc_intern_push_n( PUSH_N_N ); + break; + case FN_Pop_N: + rc_push_num( rc_intern_pop_n() ); + break; + case FN_Push_S: + rc_intern_push_s( PUSH_S_S$ ); + break; + case FN_Pop_S$: + rc_push_str( rc_intern_pop_s() ); + break; + case FN_Stack_Size_N: + rc_push_num( rc_intern_n_stack_size() ); + break; + case FN_Stack_Size_S: + rc_push_num( rc_intern_s_stack_size() ); + break; + case FN_FileOpen: + rc_push_num( rc_intern_fileOpen( FILEOPEN_STREAM, FILEOPEN_FILENAME$, FILEOPEN_MODE ) ); + break; + case FN_FileClose: + rc_intern_fileClose( FILECLOSE_STREAM ); + break; + case FN_ReadByte: + rc_push_num( rc_intern_fileReadByte( READBYTE_STREAM ) ); + break; + case FN_WriteByte: + rc_intern_fileWriteByte( WRITEBYTE_STREAM, WRITEBYTE_BYTE ); + break; + case FN_ReadLine$: + rc_push_str( rc_intern_fileReadLine( READLINE$_STREAM ) ); + break; + case FN_Write: + rc_intern_fileWrite( WRITE_STREAM, WRITE_TXT$ ); + break; + case FN_WriteLine: + rc_intern_fileWriteLine( WRITELINE_STREAM, WRITELINE_TXT$ ); + break; + case FN_CopyFile: + rc_intern_fileCopy( COPYFILE_SRC$, COPYFILE_DST$ ); + break; + case FN_RemoveFile: + rc_push_num( rc_intern_fileDelete( REMOVEFILE_FILENAME$ ) ); + break; + case FN_FileExists: + rc_push_num( rc_intern_fileExist( FILEEXISTS_FILENAME$ ) ); + break; + case FN_MoveFile: + rc_push_num( rc_intern_fileMove( MOVEFILE_SRC$, MOVEFILE_DST$ ) ); + break; + case FN_RenameFile: + rc_push_num( rc_intern_fileRename( RENAMEFILE_SRC$, RENAMEFILE_DST$ ) ); + break; + case FN_FileLength: + rc_push_num( rc_intern_fileLength( FILELENGTH_FILENAME$ ) ); + break; + case FN_Tell: + rc_push_num( rc_intern_fileTell( TELL_STREAM ) ); + break; + case FN_Seek: + rc_push_num( rc_intern_fileSeek( SEEK_STREAM, SEEK_POS ) ); + break; + case FN_EOF: + rc_push_num( rc_intern_eof( EOF_STREAM ) ); + break; + case FN_FreeFile: + rc_push_num( rc_intern_freeFile() ); + break; + case FN_ChangeDir: + rc_intern_dirChange( CHANGEDIR_P$ ); + break; + case FN_DirExists: + rc_push_num( rc_intern_dirExist( DIREXISTS_P$ ) ); + break; + case FN_DirFirst$: + rc_push_str( rc_intern_dirFirst() ); + break; + case FN_Dir$: + rc_push_str( rc_intern_dir() ); + break; + case FN_DirNext$: + rc_push_str( rc_intern_dirNext() ); + break; + case FN_MakeDir: + rc_push_num( rc_intern_dirCreate( MAKEDIR_P$ ) ); + break; + case FN_RemoveDir: + rc_push_num( rc_intern_dirDelete( REMOVEDIR_P$ ) ); + break; + case FN_Date$: + rc_push_str( rc_intern_date() ); + break; + case FN_Easter$: + rc_push_str( rc_intern_easter(EASTER$_YEAR) ); + break; + case FN_Ticks: + rc_push_num( rc_intern_ticks() ); + break; + case FN_Time$: + rc_push_str( rc_intern_time() ); + break; + case FN_Timer: + rc_push_num( rc_intern_timer() ); + break; + case FN_Wait: + rc_intern_wait( WAIT_M_SEC ); + break; + case FN_WindowOpen: //Sub Procedure + rc_media_openWindow_hw( WINDOWOPEN_WIN, WINDOWOPEN_TITLE$, WINDOWOPEN_X, WINDOWOPEN_Y, WINDOWOPEN_W, WINDOWOPEN_H, WINDOWOPEN_FLAG, WINDOWOPEN_VSYNC); + break; + case FN_WindowClose: //Sub Procedure + rc_media_closeWindow_hw( WINDOWCLOSE_WIN ); + break; + case FN_RaiseWindow: //Sub Procedure + rc_media_raiseWindow( RAISEWINDOW_WIN ); + break; + case FN_Window: //Sub Procedure + rc_media_setActiveWindow( WINDOW_WIN ); + break; + case FN_Update: //Sub Procedure + //cout << "update call" << endl; + rc_events(); + rc_media_updateWindow_hw(); + #ifdef RC_WEB + emscripten_sleep(0); + #else + SDL_Delay(0); + #endif // RC_WEB + break; + case FN_Cls: //Sub Procedure + rc_media_cls(); + break; + case FN_SetClearColor: + rc_media_setClearColor( SETCLEARCOLOR_C ); + break; + case FN_ShowWindow: //Sub Procedure + rc_media_showWindow( SHOWWINDOW_WIN ); + break; + case FN_HideWindow: //Sub Procedure + rc_media_hideWindow( HIDEWINDOW_WIN ); + break; + case FN_SetWindowTitle: //Sub Procedure + rc_media_setWindowTitle( SETWINDOWTITLE_WIN, SETWINDOWTITLE_TITLE$ ); + break; + case FN_WindowTitle$: //String Function + rc_push_str( rc_media_getWindowTitle( WINDOWTITLE$_WIN )); + break; + case FN_SetWindowPosition: //Sub Procedure + rc_media_setWindowPosition( SETWINDOWPOSITION_WIN, SETWINDOWPOSITION_X, SETWINDOWPOSITION_Y ); + break; + case FN_GetWindowPosition: //Sub Procedure + rc_media_getWindowPosition( SETWINDOWPOSITION_WIN, &SETWINDOWPOSITION_X, &SETWINDOWPOSITION_Y ); + break; + case FN_SetWindowSize: //Sub Procedure + rc_media_setWindowSize( SETWINDOWSIZE_WIN, SETWINDOWSIZE_W, SETWINDOWSIZE_H ); + break; + case FN_GetWindowSize: //Sub Procedure + rc_media_getWindowSize( GETWINDOWSIZE_WIN, &GETWINDOWSIZE_W, &GETWINDOWSIZE_H); + break; + case FN_SetWindowMinSize: //Sub Procedure + rc_media_setWindowMinSize( SETWINDOWMINSIZE_WIN, SETWINDOWMINSIZE_W, SETWINDOWMINSIZE_H ); + break; + case FN_GetWindowMinSize: //Sub Procedure + rc_media_getWindowMinSize( GETWINDOWMINSIZE_WIN, &GETWINDOWMINSIZE_W, &GETWINDOWMINSIZE_H ); + break; + case FN_SetWindowMaxSize: //Sub Procedure + rc_media_setWindowMaxSize( SETWINDOWMAXSIZE_WIN, SETWINDOWMAXSIZE_W, SETWINDOWMAXSIZE_H ); + break; + case FN_GetWindowMaxSize: //Sub Procedure + rc_media_getWindowMaxSize( GETWINDOWMAXSIZE_WIN, &GETWINDOWMAXSIZE_W, &GETWINDOWMAXSIZE_H ); + break; + case FN_WindowIsFullscreen: //Number Function + rc_push_num( rc_media_windowIsFullscreen( WINDOWISFULLSCREEN_WIN ) ); + break; + case FN_WindowIsVisible: //Number Function + rc_push_num( rc_media_windowIsVisible( WINDOWISVISIBLE_WIN ) ); + break; + case FN_WindowIsBordered: //Number Function + rc_push_num( rc_media_windowIsBordered( WINDOWISBORDERED_WIN ) ); + break; + case FN_WindowIsResizable: //Number Function + rc_push_num( rc_media_windowIsResizable( WINDOWISRESIZABLE_WIN ) ); + break; + case FN_WindowIsMinimized: //Number Function + rc_push_num( rc_media_windowIsMinimized( WINDOWISMINIMIZED_WIN ) ); + break; + case FN_WindowIsMaximized: //Number Function + rc_push_num( rc_media_windowIsMaximized( WINDOWISMAXIMIZED_WIN ) ); + break; + case FN_WindowHasInputFocus: //Number Function + rc_push_num( rc_media_windowHasInputFocus( WINDOWHASINPUTFOCUS_WIN ) ); + break; + case FN_WindowHasMouseFocus: //Number Function + rc_push_num( rc_media_windowHasMouseFocus( WINDOWHASMOUSEFOCUS_WIN ) ); + break; + case FN_SetWindowFullscreen: //Sub Procedure + rc_media_setWindowFullscreen( SETWINDOWFULLSCREEN_WIN, SETWINDOWFULLSCREEN_FLAG ); + rc_media_cls(); + break; + case FN_MaximizeWindow: //Sub Procedure + rc_media_maximizeWindow( MAXIMIZEWINDOW_WIN ); + break; + case FN_MinimizeWindow: //Sub Procedure + rc_media_minimizeWindow( MINIMIZEWINDOW_WIN ); + break; + case FN_SetWindowBorder: //Sub Procedure + rc_media_setWindowBordered( SETWINDOWBORDER_WIN, SETWINDOWBORDER_FLAG ); + break; + case FN_WindowClip: //Sub Procedure + rc_media_getWindowClip_hw( WINDOWCLIP_SLOT, WINDOWCLIP_X, WINDOWCLIP_Y, WINDOWCLIP_W, WINDOWCLIP_H ); + break; + case FN_WindowExists: //Number Function + rc_push_num( rc_media_windowExists( WINDOWEXISTS_WIN ) ); + break; + case FN_NumWindows: //Number Function + rc_push_num( rc_media_numWindows() ); + break; + case FN_WindowEvent_Close: //Number Function + rc_push_num( rc_media_windowEvent_Close( WINDOWEVENT_CLOSE_WIN ) ); + break; + case FN_WindowEvent_Maximize: //Number Function + rc_push_num( rc_media_windowEvent_Maximize( WINDOWEVENT_MAXIMIZE_WIN ) ); + break; + case FN_WindowEvent_Minimize: //Number Function + rc_push_num( rc_media_windowEvent_Minimize( WINDOWEVENT_MINIMIZE_WIN ) ); + break; + case FN_ActiveWindow: + rc_push_num(rc_active_window); + break; + case FN_SetWindowIcon: + rc_media_setWindowIcon( SETWINDOWICON_WIN, SETWINDOWICON_SLOT ); + break; + case FN_FPS: + rc_push_num(rc_fps[rc_active_window]); + break; + case FN_CanvasOpen: //Sub Procedure + rc_media_openScreen_hw( CANVASOPEN_C_NUM, CANVASOPEN_W, CANVASOPEN_H, CANVASOPEN_VIEWPORT_X, CANVASOPEN_VIEWPORT_Y, CANVASOPEN_VIEWPORT_W, CANVASOPEN_VIEWPORT_H, CANVASOPEN_MODE); + break; + case FN_CanvasClose: //Sub Procedure + rc_media_closeScreen_hw( CANVASCLOSE_C_NUM ); + break; + case FN_SetCanvasVisible: //Sub Procedure + rc_media_setScreenVisible( SETCANVASVISIBLE_C_NUM, SETCANVASVISIBLE_FLAG ); + break; + case FN_CanvasIsVisible: //Number Function + rc_push_num( rc_media_screenIsVisible( CANVASISVISIBLE_C_NUM ) ); + break; + case FN_SetCanvasViewport: //Sub Procedure + rc_media_setScreenViewport( SETCANVASVIEWPORT_CNUM, SETCANVASVIEWPORT_X, SETCANVASVIEWPORT_Y, SETCANVASVIEWPORT_W, SETCANVASVIEWPORT_H ); + break; + case FN_GetCanvasViewport: //Sub Procedure + rc_media_getScreenViewport( GETCANVASVIEWPORT_C_NUM, &GETCANVASVIEWPORT_X, &GETCANVASVIEWPORT_Y, &GETCANVASVIEWPORT_W, &GETCANVASVIEWPORT_H ); + break; + case FN_Canvas: //Sub Procedure + rc_media_screen_hw( CANVAS_C_NUM ); + break; + case FN_SetCanvasOffset: //Sub Procedure + rc_media_screenOffset( SETCANVASOFFSET_C_NUM, SETCANVASOFFSET_X, SETCANVASOFFSET_Y ); + break; + case FN_GetCanvasOffset: //Sub Procedure + rc_media_getScreenOffset( GETCANVASOFFSET_C_NUM, &GETCANVASOFFSET_X, &GETCANVASOFFSET_Y ); + break; + case FN_GetCanvasSize: //Sub Procedure + rc_media_getScreenSize( GETCANVASSIZE_C_NUM, &GETCANVASSIZE_W, &GETCANVASSIZE_H ); + break; + case FN_ClearCanvas: //Sub Procedure + rc_media_clearScreen_hw(); + break; + case FN_SetCanvasAlpha: //Sub Procedure + rc_media_setScreenAlpha_hw( SETCANVASALPHA_C_NUM, SETCANVASALPHA_A ); + break; + case FN_CanvasAlpha: + rc_push_num(rc_media_ScreenAlpha_hw(CANVASALPHA_C_NUM)); + break; + case FN_SetCanvasBlendMode: + rc_push_num(rc_media_setScreenBlendMode_hw(SETCANVASBLENDMODE_C_NUM, SETCANVASBLENDMODE_BLEND_MODE)); + break; + case FN_CanvasBlendMode: + rc_push_num(rc_media_screenBlendMode_hw(CANVASBLENDMODE_C_NUM)); + break; + case FN_SetCanvasColorMod: + rc_push_num(rc_media_setScreenColorMod_hw(SETCANVASCOLORMOD_C_NUM, SETCANVASCOLORMOD_C)); + break; + case FN_CanvasColorMod: + rc_push_num(rc_media_screenColorMod_hw(CANVASCOLORMOD_C_NUM)); + break; + case FN_CopyCanvas: //Sub Procedure + rc_media_copyScreen_hw( COPYCANVAS_SRC, COPYCANVAS_X, COPYCANVAS_Y, COPYCANVAS_W, COPYCANVAS_H, COPYCANVAS_DST, COPYCANVAS_DX, COPYCANVAS_DY ); + break; + case FN_CloneCanvas: //Sub Procedure + rc_media_cloneScreen_hw( CLONECANVAS_SRC, CLONECANVAS_DST ); + break; + case FN_SetCanvasZ: //Sub Procedure + rc_media_setScreenZ( SETCANVASZ_C_NUM, SETCANVASZ_Z ); + break; + case FN_CanvasZ: + rc_push_num( rc_media_screenZ( CANVASZ_C_NUM) ); + break; + case FN_CanvasClip: //Sub Procedure + rc_media_getScreenClip2_hw( CANVASCLIP_SLOT, CANVASCLIP_X, CANVASCLIP_Y, CANVASCLIP_W, CANVASCLIP_H, CANVASCLIP_FLAG ); + break; + case FN_ActiveCanvas: + rc_push_num(rc_active_screen); + break; + case FN_Box: //Sub Procedure + rc_media_box_hw( BOX_X1, BOX_Y1, BOX_X2, BOX_Y2 ); + break; + case FN_BoxFill: //Sub Procedure + rc_media_boxFill_hw( BOXFILL_X1, BOXFILL_Y1, BOXFILL_X2, BOXFILL_Y2 ); + break; + case FN_Circle: //Sub Procedure + rc_media_circle_hw( CIRCLE_X, CIRCLE_Y, CIRCLE_RADIUS ); + break; + case FN_CircleFill: //Sub Procedure + rc_media_circleFill_hw( CIRCLEFILL_X, CIRCLEFILL_Y, CIRCLEFILL_RADIUS ); + break; + case FN_Ellipse: //Sub Procedure + rc_media_ellipse_hw( ELLIPSE_X, ELLIPSE_Y, ELLIPSE_RX, ELLIPSE_RY ); + break; + case FN_EllipseFill: //Sub Procedure + rc_media_ellipseFill_hw( ELLIPSEFILL_X, ELLIPSEFILL_Y, ELLIPSEFILL_RX, ELLIPSEFILL_RY ); + break; + case FN_FloodFill: //Sub Procedure + //cout << "FLOOD_X = " << FLOODFILL_X << endl; + rc_media_floodFill_hw( FLOODFILL_X, FLOODFILL_Y ); + break; + case FN_GetPixel: //Number Function + rc_push_num( rc_media_getPixel_hw( GETPIXEL_X, GETPIXEL_Y ) ); + break; + case FN_SetColor: //Sub Procedure + rc_media_ink( SETCOLOR_C ); + break; + case FN_Line: //Sub Procedure + rc_media_line_hw( LINE_X1, LINE_Y1, LINE_X2, LINE_Y2 ); + break; + case FN_Poly: //Sub Procedure + rc_media_poly( POLY_N, &POLY_X, &POLY_Y ); + break; + case FN_PolyFill: //Sub Procedure + rc_media_polyfill( POLYFILL_N, &POLYFILL_X, &POLYFILL_Y ); + break; + case FN_Rect: //Sub Procedure + rc_media_rectangle( RECT_X, RECT_Y, RECT_W, RECT_H ); + break; + case FN_RectFill: //Sub Procedure + rc_media_rectangleFill( RECTFILL_X, RECTFILL_Y, RECTFILL_W, RECTFILL_H ); + break; + case FN_RoundRect: //Sub Procedure + rc_media_roundRect( ROUNDRECT_X, ROUNDRECT_Y, ROUNDRECT_W, ROUNDRECT_H, ROUNDRECT_R); + break; + case FN_RoundRectFill: //Sub Procedure + rc_media_roundRectFill( ROUNDRECTFILL_X, ROUNDRECTFILL_Y, ROUNDRECTFILL_W, ROUNDRECTFILL_H, ROUNDRECTFILL_R ); + break; + case FN_RGB: //Sub Procedure + rc_push_num( rc_media_rgb( RGB_R, RGB_G, RGB_B ) ); + break; + case FN_RGBA: //Sub Procedure + rc_push_num( rc_media_rgba( RGBA_R, RGBA_G, RGBA_B, RGBA_A ) ); + break; + case FN_PSet: //Sub Procedure + rc_media_drawPixel_hw( PSET_X, PSET_Y ); + break; + case FN_LoadImage: //Sub Procedure + rc_media_loadImage_hw( LOADIMAGE_SLOT, LOADIMAGE_IMG$ ); + break; + case FN_LoadImage_Ex: //Sub Procedure + rc_media_loadImage_ex_hw( LOADIMAGE_EX_SLOT, LOADIMAGE_EX_IMG$, LOADIMAGE_EX_COLKEY ); + break; + case FN_ImageFromBuffer: //Sub Procedure + rc_media_createImage_hw( IMAGEFROMBUFFER_SLOT, IMAGEFROMBUFFER_W, IMAGEFROMBUFFER_H, &IMAGEFROMBUFFER_BUFFER ); + break; + case FN_ImageFromBuffer_Ex: //Sub Procedure + rc_media_createImage_Ex_hw( IMAGEFROMBUFFER_EX_SLOT, IMAGEFROMBUFFER_EX_W, IMAGEFROMBUFFER_EX_H, &IMAGEFROMBUFFER_EX_BUFFER, IMAGEFROMBUFFER_EX_COLKEY ); + break; + case FN_BufferFromImage: + rc_media_bufferFromImage(BUFFERFROMIMAGE_SLOT, &BUFFERFROMIMAGE_BUFFER); + break; + case FN_ImageExists: //Number Function + rc_push_num( rc_media_imageExist_hw( IMAGEEXISTS_SLOT ) ); + break; + case FN_ColorKey: //Sub Procedure + rc_media_colorKey_hw( COLORKEY_SLOT, COLORKEY_C ); + break; + case FN_CopyImage: //Sub Procedure + rc_media_copyImage_hw( COPYIMAGE_SRC, COPYIMAGE_DST ); + break; + case FN_DeleteImage: //Sub Procedure + rc_media_deleteImage_hw( DELETEIMAGE_SLOT ); + break; + case FN_SetImageAlpha: //Sub Procedure + rc_media_setImageAlpha_hw( SETIMAGEALPHA_SLOT, SETIMAGEALPHA_A ); + break; + case FN_ImageAlpha: //Number Function + rc_push_num( rc_media_getImageAlpha_hw( IMAGEALPHA_SLOT ) ); + break; + case FN_GetImageSize: //Sub Procedure + rc_media_getImageSize_hw( GETIMAGESIZE_SLOT, &GETIMAGESIZE_W, &GETIMAGESIZE_H ); + break; + case FN_SetImageBlendMode: + rc_push_num(rc_media_setImageBlendMode_hw(SETIMAGEBLENDMODE_SLOT, SETIMAGEBLENDMODE_BLEND_MODE)); + break; + case FN_ImageBlendMode: + rc_push_num(rc_media_imageBlendMode_hw(IMAGEBLENDMODE_SLOT)); + break; + case FN_SetImageColorMod: + rc_push_num(rc_media_setImageColorMod_hw(SETIMAGECOLORMOD_SLOT, SETIMAGECOLORMOD_C)); + break; + case FN_ImageColorMod: + rc_push_num(rc_media_imageColorMod_hw(IMAGECOLORMOD_SLOT)); + break; + case FN_DrawImage: //Sub Procedure + rc_media_drawImage_hw( DRAWIMAGE_SLOT, DRAWIMAGE_X, DRAWIMAGE_Y ); + break; + case FN_DrawImage_Blit: //Sub Procedure + rc_media_drawImage_Clip_hw( DRAWIMAGE_BLIT_SLOT, DRAWIMAGE_BLIT_X, DRAWIMAGE_BLIT_Y, DRAWIMAGE_BLIT_SRC_X, DRAWIMAGE_BLIT_SRC_Y, DRAWIMAGE_BLIT_SRC_W, DRAWIMAGE_BLIT_SRC_H ); + break; + case FN_DrawImage_Blit_Ex: //Sub Procedure + rc_media_drawImage_Blit_hw( DRAWIMAGE_BLIT_EX_SLOT, DRAWIMAGE_BLIT_EX_X, DRAWIMAGE_BLIT_EX_Y, DRAWIMAGE_BLIT_EX_W, DRAWIMAGE_BLIT_EX_H, + DRAWIMAGE_BLIT_EX_SRC_X, DRAWIMAGE_BLIT_EX_SRC_Y, DRAWIMAGE_BLIT_EX_SRC_W, DRAWIMAGE_BLIT_EX_SRC_H ); + break; + case FN_DrawImage_Rotate: //Sub Procedure + rc_media_rotateImage_hw( DRAWIMAGE_ROTATE_SLOT, DRAWIMAGE_ROTATE_X, DRAWIMAGE_ROTATE_Y, DRAWIMAGE_ROTATE_ANGLE ); + break; + case FN_DrawImage_Rotate_Ex: //Sub Procedure + rc_media_rotateImageEX_hw( DRAWIMAGE_ROTATE_EX_SLOT, DRAWIMAGE_ROTATE_EX_X, DRAWIMAGE_ROTATE_EX_Y, DRAWIMAGE_ROTATE_EX_SRC_X, DRAWIMAGE_ROTATE_EX_SRC_Y, + DRAWIMAGE_ROTATE_EX_SRC_W, DRAWIMAGE_ROTATE_EX_SRC_H, DRAWIMAGE_ROTATE_EX_ANGLE ); + break; + case FN_DrawImage_Zoom: //Sub Procedure + rc_media_zoomImage_hw( DRAWIMAGE_ZOOM_SLOT, DRAWIMAGE_ZOOM_X, DRAWIMAGE_ZOOM_Y, DRAWIMAGE_ZOOM_ZX, DRAWIMAGE_ZOOM_ZY ); + break; + case FN_DrawImage_Zoom_Ex: //Sub Procedure + rc_media_zoomImageEX_hw( DRAWIMAGE_ZOOM_EX_SLOT, DRAWIMAGE_ZOOM_EX_X, DRAWIMAGE_ZOOM_EX_Y, DRAWIMAGE_ZOOM_EX_SRC_X, DRAWIMAGE_ZOOM_EX_SRC_Y, + DRAWIMAGE_ZOOM_EX_SRC_W, DRAWIMAGE_ZOOM_EX_SRC_H, DRAWIMAGE_ZOOM_EX_ZX, DRAWIMAGE_ZOOM_EX_ZY ); + break; + case FN_DrawImage_Rotozoom: //Sub Procedure + rc_media_rotozoomImage_hw( DRAWIMAGE_ROTOZOOM_SLOT, DRAWIMAGE_ROTOZOOM_X, DRAWIMAGE_ROTOZOOM_Y, DRAWIMAGE_ROTOZOOM_ANGLE, + DRAWIMAGE_ROTOZOOM_ZX, DRAWIMAGE_ROTOZOOM_ZY ); + break; + case FN_DrawImage_Rotozoom_Ex: //Sub Procedure + rc_media_rotozoomImageEX_hw( DRAWIMAGE_ROTOZOOM_EX_SLOT, DRAWIMAGE_ROTOZOOM_EX_X, DRAWIMAGE_ROTOZOOM_EX_Y, DRAWIMAGE_ROTOZOOM_EX_SRC_X, DRAWIMAGE_ROTOZOOM_EX_SRC_Y, + DRAWIMAGE_ROTOZOOM_EX_SRC_W, DRAWIMAGE_ROTOZOOM_EX_SRC_H, DRAWIMAGE_ROTOZOOM_EX_ANGLE, DRAWIMAGE_ROTOZOOM_EX_ZX, DRAWIMAGE_ROTOZOOM_EX_ZY ); + break; + case FN_DrawImage_Flip: + rc_media_drawImage_Flip( DRAWIMAGE_FLIP_SLOT, DRAWIMAGE_FLIP_X, DRAWIMAGE_FLIP_Y, DRAWIMAGE_FLIP_H, DRAWIMAGE_FLIP_V ); + break; + case FN_DrawImage_Flip_Ex: + rc_media_drawImage_Flip_Ex(DRAWIMAGE_FLIP_EX_SLOT, DRAWIMAGE_FLIP_EX_X, DRAWIMAGE_FLIP_EX_Y, DRAWIMAGE_FLIP_EX_SRC_X, DRAWIMAGE_FLIP_EX_SRC_Y, DRAWIMAGE_FLIP_EX_SRC_W, + DRAWIMAGE_FLIP_EX_SRC_H, DRAWIMAGE_FLIP_EX_H, DRAWIMAGE_FLIP_EX_V); + break; + case FN_InKey: //Number Function + rc_push_num( rc_media_inkey() ); + break; + case FN_Key: //Number Function + rc_push_num( rc_media_key( KEY_KEY_CODE ) ); + break; + case FN_WaitKey: //Number Function + rc_push_num( rc_media_waitKey() ); + break; + case FN_HideMouse: //Sub Procedure + rc_media_hideMouse(); + break; + case FN_ShowMouse: //Sub Procedure + rc_media_showMouse(); + break; + case FN_MouseIsVisible: //Number Function + rc_push_num( rc_media_mouseIsVisible() ); + break; + case FN_GetMouse: //Sub Procedure + rc_media_getMouse( &GETMOUSE_X, &GETMOUSE_Y, &GETMOUSE_MB1, &GETMOUSE_MB2, &GETMOUSE_MB3 ); + break; + case FN_MouseX: //Number Function + rc_push_num( rc_media_mouseX() ); + break; + case FN_MouseY: //Number Function + rc_push_num( rc_media_mouseY() ); + break; + case FN_MouseButton: //Number Function + rc_push_num( rc_media_mouseButton( MOUSEBUTTON_MB ) ); + break; + case FN_GetMouseWheel: //Sub Procedure + rc_media_getMouseWheel( &GETMOUSEWHEEL_X_AXIS, &GETMOUSEWHEEL_Y_AXIS ); + break; + case FN_MouseWheelX: //Number Function + rc_push_num( rc_media_mouseWheelX() ); + break; + case FN_MouseWheelY: //Number Function + rc_push_num( rc_media_mouseWheelY() ); + break; + case FN_SoundFromBuffer: //Sub Procedure + rc_media_createSound( SOUNDFROMBUFFER_SLOT, &SOUNDFROMBUFFER_BUFFER, SOUNDFROMBUFFER_BUFFER_SIZE, SOUNDFROMBUFFER_VOL ); + break; + case FN_LoadSound: //Sub Procedure + rc_media_loadSound( LOADSOUND_SLOT, LOADSOUND_SND_FILE$ ); + break; + case FN_LoadMusic: //Sub Procedure + rc_media_loadMusic( LOADMUSIC_MUSIC_FILE$ ); + break; + case FN_PlaySound: //Sub Procedure + rc_media_playSound( PLAYSOUND_SLOT, PLAYSOUND_CHANNEL, PLAYSOUND_LOOPS ); + break; + case FN_PlaySoundTimed: //Sub Procedure + rc_media_playSoundTimed( PLAYSOUNDTIMED_SLOT, PLAYSOUNDTIMED_CHANNEL, PLAYSOUNDTIMED_LOOPS, PLAYSOUNDTIMED_MS ); + break; + case FN_PlayMusic: //Sub Procedure + rc_media_playMusic( PLAYMUSIC_MLOOPS ); + break; + case FN_PauseSound: //Sub Procedure + rc_media_pauseSound( PAUSESOUND_CHANNEL ); + break; + case FN_ResumeSound: //Sub Procedure + rc_media_resumeSound( RESUMESOUND_CHANNEL ); + break; + case FN_PauseMusic: //Sub Procedure + rc_media_pauseMusic(); + break; + case FN_ResumeMusic: //Sub Procedure + rc_media_resumeMusic(); + break; + case FN_DeleteSound: //Sub Procedure + rc_media_deleteSound( DELETESOUND_SLOT ); + break; + case FN_DeleteMusic: //Sub Procedure + rc_media_deleteMusic(); + break; + case FN_FadeMusicIn: //Sub Procedure + rc_media_fadeMusicIn( FADEMUSICIN_FADE_TIME, FADEMUSICIN_LOOPS ); + break; + case FN_FadeMusicOut: //Sub Procedure + rc_media_fadeMusicOut( FADEMUSICOUT_FADE_TIME ); + break; + case FN_MusicExists: //Number Function + rc_push_num( rc_media_musicExists() ); + break; + case FN_SetMusicVolume: //Sub Procedure + rc_media_setMusicVolume( SETMUSICVOLUME_VOL ); + break; + case FN_MusicVolume: //Number Function + rc_push_num( rc_media_getMusicVolume() ); + break; + case FN_SetMusicPosition: //Sub Procedure + rc_media_setMusicPosition( SETMUSICPOSITION_POS ); + break; + case FN_MusicPosition: //Number Function + rc_push_num( rc_media_getMusicPosition() ); + break; + case FN_RewindMusic: //Sub Procedure + rc_media_rewindMusic(); + break; + case FN_SetSoundChannels: //Sub Procedure + rc_media_setSoundChannels( SETSOUNDCHANNELS_MAX_CHANNELS ); + break; + case FN_NumSoundChannels: //Number Function + rc_push_num( rc_media_getSoundChannels() ); + break; + case FN_SoundIsEnabled: //Number Function + rc_push_num( rc_media_soundIsEnabled() ); + break; + case FN_SoundExists: //Number Function + rc_push_num( rc_media_soundExists( SOUNDEXISTS_SLOT ) ); + break; + case FN_SetChannelVolume: //Sub Procedure + rc_media_setChannelVolume( SETCHANNELVOLUME_CHANNEL, SETCHANNELVOLUME_VOL ); + break; + case FN_ChannelVolume: //Number Function + rc_push_num( rc_media_getChannelVolume( CHANNELVOLUME_CHANNEL ) ); + break; + case FN_SetSoundVolume: //Sub Procedure + rc_media_setSoundVolume( SETSOUNDVOLUME_SLOT, SETSOUNDVOLUME_VOL ); + break; + case FN_SoundVolume: //Number Function + rc_push_num( rc_media_getSoundVolume( SOUNDVOLUME_SLOT ) ); + break; + case FN_StopMusic: //Sub Procedure + rc_media_stopMusic(); + break; + case FN_StopSound: //Sub Procedure + rc_media_stopSound( STOPSOUND_CHANNEL ); + break; + case FN_ChannelIsPlaying: + rc_push_num( rc_media_channelIsPlaying( CHANNELISPLAYING_CHANNEL )); + break; + case FN_ChannelIsPaused: + rc_push_num( rc_media_channelIsPaused( CHANNELISPAUSED_CHANNEL )); + break; + case FN_SetChannelDistance: + rc_push_num( rc_media_setChannelDistance( SETCHANNELDISTANCE_CHANNEL, SETCHANNELDISTANCE_DIST_VALUE ) ); + break; + case FN_SetChannelPanning: + rc_push_num( rc_media_setChannelPanning( SETCHANNELPANNING_CHANNEL, SETCHANNELPANNING_LEFT_VALUE, SETCHANNELPANNING_RIGHT_VALUE ) ); + break; + case FN_NumJoysticks: //Number Function + rc_push_num( rc_media_numJoysticks() ); + break; + case FN_NumJoyAxes: //Number Function + rc_push_num( rc_media_numJoyAxes( NUMJOYAXES_JOY_NUM ) ); + break; + case FN_NumJoyButtons: //Number Function + rc_push_num( rc_media_numJoyButtons( NUMJOYBUTTONS_JOY_NUM ) ); + break; + case FN_NumJoyHats: //Number Function + rc_push_num( rc_media_numJoyHats( NUMJOYHATS_JOY_NUM ) ); + break; + case FN_NumJoyTrackBalls: //Number Function + rc_push_num( rc_media_numJoyTrackBalls( NUMJOYTRACKBALLS_JOY_NUM ) ); + break; + case FN_JoyAxis: //Number Function + rc_push_num( rc_media_joyAxis( JOYAXIS_JOY_NUM, JOYAXIS_JOY_AXIS ) ); + break; + case FN_JoyButton: //Number Function + rc_push_num( rc_media_joyButton( JOYBUTTON_JOY_NUM, JOYBUTTON_JOY_BUTTON ) ); + break; + case FN_JoyHat: //Number Function + rc_push_num( rc_media_joyHat( JOYHAT_JOY_NUM, JOYHAT_JOY_HAT ) ); + break; + case FN_GetJoyTrackBall: //Sub Procedure + rc_media_getJoyTrackBall( GETJOYTRACKBALL_JOY_NUM, GETJOYTRACKBALL_BALL, &GETJOYTRACKBALL_DX, &GETJOYTRACKBALL_DY ); + break; + case FN_JoyName$: //String Function + rc_push_str( rc_media_joystickName( JOYNAME$_JOY_NUM ) ); + break; + case FN_JoystickIsConnected: //Number Function + rc_push_num( rc_media_joystickIsConnected( JOYSTICKISCONNECTED_JOY_NUM ) ); + break; + case FN_GetCursor: //Sub Procedure + rc_media_getCursor( &GETCURSOR_X, &GETCURSOR_Y ); + break; + case FN_PrintS: //Sub Procedure + rc_media_printS_hw( PRINTS_TXT$ ); + break; + case FN_InputS$: //String Function + rc_push_str( rc_media_inputS_hw( INPUTS$_PROMPT$ ) ); + break; + case FN_ZoneInputS$: //String Function + rc_push_str( rc_media_ZoneInputS_hw( ZONEINPUTS$_X, ZONEINPUTS$_Y, ZONEINPUTS$_W, ZONEINPUTS$_H ) ); + break; + case FN_Locate: //Sub Procedure + rc_media_locate( LOCATE_X, LOCATE_Y ); + break; + case FN_ReadInput_Start: //Sub Procedure + rc_media_ReadInput_Start(); + break; + case FN_ReadInput_Stop: //Sub Procedure + rc_media_ReadInput_Stop(); + break; + case FN_ReadInput_Text$: //String Function + rc_push_str( rc_media_ReadInput_Text() ); + break; + case FN_ReadInput_SetText: //Sub Procedure + rc_media_ReadInput_SetText( READINPUT_SETTEXT_TXT$ ); + break; + case FN_ReadInput_ToggleBackspace: //Sub Procedure + rc_media_ReadInput_ToggleBackspace( READINPUT_TOGGLEBACKSPACE_FLAG ); + break; + case FN_LoadFont: //Sub Procedure + rc_media_LoadFont( LOADFONT_SLOT, LOADFONT_FNT_FILE$, LOADFONT_SIZE ); + break; + case FN_DeleteFont: //Sub Procedure + rc_media_DeleteFont( DELETEFONT_SLOT ); + break; + case FN_FontIsLoaded: //Number Function + rc_push_num( rc_media_fontIsLoaded( FONTISLOADED_SLOT ) ); + break; + case FN_Font: //Sub Procedure + rc_media_font( FONT_SLOT ); + break; + case FN_SetFontStyle: //Sub Procedure + rc_media_setFontStyle( SETFONTSTYLE_SLOT, SETFONTSTYLE_STYLE ); + break; + case FN_DrawText: //Sub Procedure + rc_media_drawText_hw( DRAWTEXT_TXT$, DRAWTEXT_X, DRAWTEXT_Y ); + break; + case FN_DrawText_Shaded: //Sub Procedure + rc_media_drawText_shaded_hw( DRAWTEXT_SHADED_TXT$, DRAWTEXT_SHADED_X, DRAWTEXT_SHADED_Y, DRAWTEXT_SHADED_FG_COLOR, DRAWTEXT_SHADED_BG_COLOR ); + break; + case FN_DrawText_Blended: //Sub Procedure + rc_media_drawText_blended_hw( DRAWTEXT_BLENDED_TXT$, DRAWTEXT_BLENDED_X, DRAWTEXT_BLENDED_Y ); + break; + case FN_RenderText: //Sub Procedure + rc_media_GetRenderedText_hw( RENDERTEXT_SLOT, RENDERTEXT_TXT$ ); + break; + case FN_GetTextSize: //Sub Procedure + rc_media_getTextSize( GETTEXTSIZE_SLOT, GETTEXTSIZE_TXT$, &GETTEXTSIZE_W, &GETTEXTSIZE_H ); + break; + case FN_TouchPressure: //Number Function + rc_push_num( rc_media_touchPressure() ); + break; + case FN_GetTouch: //Sub Procedure + rc_media_getTouch( &GETTOUCH_STATUS, &GETTOUCH_X, &GETTOUCH_Y, &GETTOUCH_DX, &GETTOUCH_DY ); + break; + case FN_GetMultiTouch: //Sub Procedure + rc_media_getMultiTouch( &GETMULTITOUCH_STATUS, &GETMULTITOUCH_X, &GETMULTITOUCH_Y, &GETMULTITOUCH_FINGERS, &GETMULTITOUCH_DIST, &GETMULTITOUCH_THETA ); + break; + case FN_GetTouchFinger: //Sub Procedure + rc_media_getTouchFinger( GETTOUCHFINGER_FINGER, &GETTOUCHFINGER_X, &GETTOUCHFINGER_Y, &GETTOUCHFINGER_PRESSURE ); + break; + case FN_NumFingers: //Number Function + rc_push_num( rc_media_numFingers() ); + break; + case FN_CheckSockets: + rc_push_num( rc_net_checkSockets( CHECKSOCKETS_TIMEOUT_MS ) ); + break; + case FN_TCP_SocketReady: + rc_push_num( rc_net_tcp_socketReady( TCP_SOCKETREADY_SOCKET ) ); + break; + case FN_UDP_SocketReady: + rc_push_num( rc_net_udp_socketReady( UDP_SOCKETREADY_SOCKET ) ); + break; + case FN_TCP_SocketOpen: //Number Function + rc_push_num( rc_net_tcp_openSocket(TCP_SOCKETOPEN_SOCKET, TCP_SOCKETOPEN_HOST$, TCP_SOCKETOPEN_PORT ) ); + break; + case FN_TCP_SocketClose: //Sub Procedure + rc_net_tcp_closeSocket( TCP_SOCKETCLOSE_SOCKET ); + break; + case FN_TCP_RemoteHost: //Number Function + rc_push_num( rc_net_tcp_remoteHost( TCP_REMOTEHOST_SOCKET ) ); + break; + case FN_TCP_RemotePort: //Number Function + rc_push_num( rc_net_tcp_remotePort( TCP_REMOTEPORT_SOCKET ) ); + break; + case FN_TCP_GetData: //Number Function + rc_push_num( rc_net_tcp_getData_str( TCP_GETDATA_SOCKET, &TCP_GETDATA_SDATA$, TCP_GETDATA_NUMBYTES ) ); + break; + case FN_TCP_SendData: //Sub Procedure + rc_net_tcp_sendData( TCP_SENDDATA_SOCKET, TCP_SENDDATA_SDATA$.c_str(), TCP_SENDDATA_SDATA$.length() ); + break; + case FN_TCP_AcceptSocket: //Number Function + rc_push_num( rc_net_tcp_acceptSocket( TCP_ACCEPTSOCKET_SERVER, TCP_ACCEPTSOCKET_CLIENT ) ); + break; + case FN_UDP_SocketOpen: //Number Function + rc_push_num( rc_net_udp_openSocket( UDP_SOCKETOPEN_SOCKET, UDP_SOCKETOPEN_PORT ) ); + break; + case FN_UDP_SocketClose: //Sub Procedure + rc_push_num(rc_net_udp_closeSocket( UDP_SOCKETCLOSE_SOCKET )); + break; + case FN_UDP_GetData: //Number Function + rc_push_num( rc_net_udp_readStream( UDP_GETDATA_SOCKET, &UDP_GETDATA_SDATA$, &UDP_GETDATA_HOST$, &UDP_GETDATA_PORT ) ); + break; + case FN_UDP_Length: //Number Function + rc_push_num( rc_net_udp_len()); + break; + case FN_UDP_MaxLength: //Number Function + rc_push_num( rc_net_udp_maxlen() ); + break; + case FN_UDP_RemoteHost$: //String Function + rc_push_str( rc_net_udp_getRemoteHost( UDP_REMOTEHOST$_SOCKET ) ); + break; + case FN_UDP_RemotePort: //Number Function + rc_push_num( rc_net_udp_getRemotePort( UDP_REMOTEPORT_SOCKET ) ); + break; + case FN_UDP_SendData: //Sub Procedure + rc_net_udp_sendData( UDP_SENDDATA_SOCKET, UDP_SENDDATA_HOST$, UDP_SENDDATA_PORT, UDP_SENDDATA_SDATA$ ); + break; + case FN_LoadVideo: //Sub Procedure + rc_media_loadVideo( LOADVIDEO_VID$ ); + break; + case FN_PlayVideo: //Sub Procedure + rc_media_playVideo( PLAYVIDEO_VLOOPS ); + break; + case FN_PauseVideo: //Sub Procedure + rc_media_pauseVideo(); + break; + case FN_StopVideo: //Sub Procedure + rc_media_stopVideo(); + break; + case FN_SetVideoPosition: //Sub Procedure + rc_media_setVideoPosition( SETVIDEOPOSITION_POS ); + break; + case FN_ResumeVideo: //Sub Procedure + rc_media_resumeVideo(); + break; + case FN_VideoPosition: //Number Function + rc_push_num( rc_media_videoPosition() ); + break; + case FN_DeleteVideo: //Sub Procedure + rc_media_deleteVideo(); + break; + case FN_VideoIsPlaying: //Number Function + rc_push_num( rc_media_videoIsPlaying() ); + break; + case FN_VideoEnd: //Number Function + rc_push_num( rc_media_videoEnd() ); + break; + case FN_GetVideoStats: //Sub Procedure + rc_media_getVideoStats( GETVIDEOSTATS_VFILE$, &GETVIDEOSTATS_VLEN, &GETVIDEOSTATS_VFPS, &GETVIDEOSTATS_FRAME_W, &GETVIDEOSTATS_FRAME_H ); + break; + case FN_SetVideoDrawRect: //Sub Procedure + rc_media_setVideoDrawRect( SETVIDEODRAWRECT_X, SETVIDEODRAWRECT_Y, SETVIDEODRAWRECT_W, SETVIDEODRAWRECT_H ); + break; + case FN_GetVideoDrawRect: //Sub Procedure + rc_media_getVideoDrawRect( &GETVIDEODRAWRECT_X, &GETVIDEODRAWRECT_Y, &GETVIDEODRAWRECT_W, &GETVIDEODRAWRECT_H ); + break; + case FN_GetVideoSize: //Sub Procedure + rc_media_getVideoSize( &GETVIDEOSIZE_W, &GETVIDEOSIZE_H ); + break; + case FN_VideoExists: //Number Function + rc_push_num( rc_media_videoExists() ); + break; + case FN_SetVideoAlpha: //Sub Procedure + rc_media_setVideoAlpha( SETVIDEOALPHA_A ); + break; + case FN_System: //Number Function + rc_push_num( rc_intern_system( SYSTEM_CMD$ ) ); + break; + case FN_OS$: //String Function + rc_push_str( rc_intern_OS()); + break; + case FN_Command$: //String Function + rc_push_str( rc_intern_command( COMMAND$_ARG ) ); + break; + case FN_NumCommands: //Number Function + rc_push_num( rc_intern_numCommands() ); + break; + case FN_Env$: //String Function + rc_push_str( rc_intern_env( ENV$_V$ ) ); + break; + case FN_SetEnv: //Sub Procedure + rc_intern_setEnv( SETENV_VAR$, SETENV_VALUE$, SETENV_OVERWRITE ); + break; + case FN_PrefPath$: //String Function + rc_push_str( rc_intern_prefPath( PREFPATH$_ORG_NAME$, PREFPATH$_APP_NAME$ ) ); + break; + case FN_ClipboardText$: + rc_push_str( rc_media_getClipboardText() ); + break; + case FN_SetClipboardText: + rc_media_setClipboardText( SETCLIPBOARDTEXT_TXT$ ); + break; + case FN_HasClipboardText: + rc_push_num( rc_media_hasClipboardText() ); + break; + case FN_Android_GetExternalStoragePath$: + rc_push_str( rc_intern_android_getExternalStoragePath() ); + break; + case FN_Android_GetExternalStorageState: + rc_push_num( rc_intern_android_getExternalStorageState() ); + break; + case FN_Android_GetInternalStoragePath$: + rc_push_str( rc_intern_android_getInternalStoragePath() ); + break; + case FN_Android_JNI_Message$: + rc_push_str( rc_intern_android_jni_message( ANDROID_JNI_MESSAGE$_ARG$ )); + break; + case FN_Runtime_Utility_Message$: + rc_push_str( rc_intern_runtime_utility( RUNTIME_UTILITY_MESSAGE$_ARG$ )); + break; + case FN_GetDesktopDisplayMode: //Sub Procedure + rc_media_getDesktopDisplayMode( GETDESKTOPDISPLAYMODE_INDEX, &GETDESKTOPDISPLAYMODE_W, &GETDESKTOPDISPLAYMODE_H, &GETDESKTOPDISPLAYMODE_FREQ); + break; + case FN_DrawImage_Transform: //Sub Procedure + rc_media_drawImage_Transform(DRAWIMAGE_TRANSFORM_SLOT, DRAWIMAGE_TRANSFORM_X, DRAWIMAGE_TRANSFORM_Y, DRAWIMAGE_TRANSFORM_W, DRAWIMAGE_TRANSFORM_H, + DRAWIMAGE_TRANSFORM_SRC_X, DRAWIMAGE_TRANSFORM_SRC_Y, DRAWIMAGE_TRANSFORM_W, DRAWIMAGE_TRANSFORM_H, DRAWIMAGE_TRANSFORM_ANGLE, + DRAWIMAGE_TRANSFORM_CENTER_X, DRAWIMAGE_TRANSFORM_CENTER_Y, DRAWIMAGE_TRANSFORM_FLIP_H, DRAWIMAGE_TRANSFORM_FLIP_V); + break; + case FN_GetPowerInfo: //Sub Procedure + rc_intern_getPowerInfo(&GETPOWERINFO_STATUS, &GETPOWERINFO_SECS, &GETPOWERINFO_PCT); + break; + case FN_SystemRam: //Number Function + rc_push_num( rc_intern_systemRam() ); + break; + case FN_SetRenderScaleQuality: //Number Function + rc_push_num( rc_media_setRenderScaleQuality((int)SETRENDERSCALEQUALITY_N) ); + break; + case FN_EvalJS$: //String Function + rc_push_str( rc_intern_evalJS( EVALJS$_JS_CODE$) ); + break; + case FN_GetRenderScaleQuality: //Number Function + rc_push_num( rc_media_getRenderScaleQuality() ); + break; + case FN_GetGlobalMouse: //Sub Procedure + rc_media_getGlobalMouse(&GETGLOBALMOUSE_X, &GETGLOBALMOUSE_Y, &GETGLOBALMOUSE_MB1, &GETGLOBALMOUSE_MB2, &GETGLOBALMOUSE_MB3); + break; + case FN_GlobalMouseX: //Number Function + rc_push_num( rc_media_globalMouseX() ); + break; + case FN_GlobalMouseY: //Number Function + rc_push_num( rc_media_globalMouseY() ); + break; + case FN_GetAccel: //Sub Procedure + rc_media_getAccel( GETACCEL_ACCEL_NUM, &GETACCEL_X, &GETACCEL_Y, &GETACCEL_Z ); + break; + case FN_AccelName$: //String Function + rc_push_str( rc_media_accelName( ACCELNAME$_ACCEL_NUM ) ); + break; + case FN_NumAccels: //Number Function + rc_push_num( rc_media_numAccels() ); + break; + case FN_GetGyro: //Sub Procedure + rc_media_getGyro( GETGYRO_GYRO_NUM, &GETGYRO_X, &GETGYRO_Y, &GETGYRO_Z ); + break; + case FN_GyroName$: //String Function + rc_push_str( rc_media_gyroName( GYRONAME$_GYRO_NUM )); + break; + case FN_NumGyros: //Number Function + rc_push_num( rc_media_numGyros() ); + break; + case FN_JoyRumblePlay: //Sub Procedure + rc_media_joyRumblePlay( JOYRUMBLEPLAY_JOY_NUM, JOYRUMBLEPLAY_STRENGTH, JOYRUMBLEPLAY_DURATION ); + break; + case FN_JoyRumbleStop: //Sub Procedure + rc_media_joyRumbleStop( JOYRUMBLESTOP_JOY_NUM ); + break; + case FN_JoystickIsHaptic: //Number Function + rc_push_num( rc_media_joystickIsHaptic( JOYSTICKISHAPTIC_JOY_NUM ) ); + break; + case FN_WriteByteBuffer: //Number Function + rc_push_num( rc_intern_fileWriteByteBuffer( WRITEBYTEBUFFER_STREAM, &WRITEBYTEBUFFER_BUF, WRITEBYTEBUFFER_BUF_SIZE ) ); + break; + case FN_ReadByteBuffer: //Number Function + rc_push_num( rc_intern_fileReadByteBuffer( READBYTEBUFFER_STREAM, &READBYTEBUFFER_BUF, READBYTEBUFFER_BUF_SIZE ) ); + break; + case FN_WindowEvent_Resize: //Number Function + rc_push_num( rc_media_windowEvent_Resize( WINDOWEVENT_RESIZE_WIN ) ); + break; + case FN_SetWindowAutoClose: //Sub Procedure + rc_media_windowEvent_setExitOnClose( SETWINDOWAUTOCLOSE_WIN, SETWINDOWAUTOCLOSE_EXIT_ON_CLOSE ); + break; + case FN_SetWindowResizable: + rc_media_setWindowResizable(SETWINDOWRESIZABLE_WIN, SETWINDOWRESIZABLE_FLAG); + break; + case FN_SystemReturnStdOut$: + rc_push_str( rc_intern_sysReturnOutput(SYSTEMRETURNSTDOUT$_CMD$) ); + break; + case FN_WindowMode: + rc_push_num( rc_media_windowMode(WINDOWMODE_VISIBLE, WINDOWMODE_FULLSCREEN, WINDOWMODE_RESIZABLE, WINDOWMODE_BORDERLESS, WINDOWMODE_HIGHDPI) ); + break; + case FN_WindowFlags: + rc_push_num( rc_media_windowFlags(WINDOWFLAGS_WIN) ); + break; + case FN_RestoreWindow: + rc_media_restoreWindow(RESTOREWINDOW_WIN); + break; + case FN_UpdateAllWindows: + rc_events(); + rc_media_updateAllWindow_hw(); + #ifdef RC_WEB + emscripten_sleep(0); + #else + SDL_Delay(0); + #endif // RC_WEB + break; + case FN_QueryAudioSpec: + rc_push_num( rc_media_queryAudioSpec(&QUERYAUDIOSPEC_FREQ, &QUERYAUDIOSPEC_FORMAT, &QUERYAUDIOSPEC_CHANNELS) ); + break; + case FN_MusicIsPlaying: + rc_push_num( rc_media_musicIsPlaying() ); + break; + case FN_DrawGeometry: //Number Function + #ifdef RC_WEB + rc_push_num(0); + #else + rc_push_num( rc_media_drawGeometry(DRAWGEOMETRY_SLOT, DRAWGEOMETRY_NUM_VERTICES, &DRAWGEOMETRY_VERTICES, DRAWGEOMETRY_NUM_INDICES, &DRAWGEOMETRY_INDICES) ); + #endif // RC_WEB + break; + case FN_Size: //Number Function + rc_push_num(rc_intern_size(SIZE_S$)); + break; + case FN_BufferFromString: //Number Function + rc_push_num(rc_intern_bufferFromString(BUFFERFROMSTRING_S$, &BUFFERFROMSTRING_BUFFER)); + break; + case FN_StringFromBuffer$: //String Function + rc_push_str( rc_intern_stringFromBuffer(&STRINGFROMBUFFER$_BUFFER, STRINGFROMBUFFER$_BUFFER_SIZE) ); + break; + case FN_GrabInput: //Sub Procedure + rc_media_grabInput(GRABINPUT_FLAG); + break; + case FN_GrabbedWindow: //Number Function + rc_push_num( rc_media_grabbedWindow() ); + break; + case FN_WarpMouse: //Sub Procedure + rc_media_warpMouse(WARPMOUSE_X, WARPMOUSEGLOBAL_Y); + break; + case FN_WarpMouseGlobal: //Sub Procedure + rc_media_warpMouseGlobal(WARPMOUSEGLOBAL_X, WARPMOUSEGLOBAL_Y); + break; + case FN_SetMouseZone: //Sub Procedure + rc_media_setMouseZone(SETMOUSEZONE_X, SETMOUSEZONE_Y, SETMOUSEZONE_W, SETMOUSEZONE_H); + break; + case FN_ClearMouseZone: //Sub Procedure + rc_media_clearMouseZone(); + break; + case FN_SetWindowAlwaysOnTop: //Sub Procedure + rc_media_setWindowAlwaysOnTop(SETWINDOWALWAYSONTOP_WIN, SETWINDOWALWAYSONTOP_FLAG); + break; + case FN_SetMouseRelative: //Sub Procedure + rc_media_setMouseRelative(SETMOUSERELATIVE_FLAG); + break; + case FN_SetWindowVSync: //Sub Procedure + rc_media_setWindowVSync(SETWINDOWVSYNC_WIN, SETWINDOWVSYNC_FLAG); + break; + case FN_OpenURL: //Number Function + rc_push_num( rc_media_openURL(OPENURL_URL$)); + break; + case FN_APIVersion$: //String Function + rc_push_str( rc_media_APIVersion() ); + break; + case FN_FlashWindow: //Number Function + rc_push_num( rc_media_flashWindow(FLASHWINDOW_WIN)); + break; + case FN_MessageBox: //Number Function + rc_push_num( rc_media_messageBox(MESSAGEBOX_TITLE$, MESSAGEBOX_MSG$)); + break; + case FN_NumberArrayCopy: //Sub Procedure + rc_number_array_copy(arr_ref_id[0], arr_ref_id[1]); + arr_ref_id.clear(); + break; + case FN_StringArrayCopy: //Sub Procedure + rc_string_array_copy(arr_ref_id[0], arr_ref_id[1]); + arr_ref_id.clear(); + break; + case FN_NumberArrayFill: //Sub Procedure + rc_number_array_fill(arr_ref_id[0], NUMBERARRAYFILL_FDATA); + arr_ref_id.clear(); + break; + case FN_StringArrayFill: //Sub Procedure + rc_string_array_fill(arr_ref_id[0], STRINGARRAYFILL_FDATA$); + arr_ref_id.clear(); + break; + case FN_Runtime$: //String Function + rc_push_str( rcbasic_runtime_path ); + break; + + + case FN_DimMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + DimMatrix(DIMMATRIX_M, DIMMATRIX_M_ROWS, DIMMATRIX_M_COLS, DIMMATRIX_PRESERVE_FLAG); + else + ProcessQueueMatrixOp(FN_DimMatrix, DIMMATRIX_M, DIMMATRIX_M_ROWS, DIMMATRIX_M_COLS, DIMMATRIX_PRESERVE_FLAG); + break; + case FN_AddMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(AddMatrix(ADDMATRIX_MA, ADDMATRIX_MB, ADDMATRIX_MC)); + else + { + ProcessQueueMatrixOp(FN_AddMatrix, ADDMATRIX_MA, ADDMATRIX_MB, ADDMATRIX_MC); + rc_push_num(1); + } + break; + case FN_AugmentMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(AugmentMatrix(AUGMENTMATRIX_MA, AUGMENTMATRIX_MB, AUGMENTMATRIX_MC)); + else + { + ProcessQueueMatrixOp(FN_AugmentMatrix, AUGMENTMATRIX_MA, AUGMENTMATRIX_MB, AUGMENTMATRIX_MC); + rc_push_num(1); + } + break; + case FN_CopyMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + CopyMatrix(COPYMATRIX_MA, COPYMATRIX_MB); + else + ProcessQueueMatrixOp(FN_CopyMatrix, COPYMATRIX_MA, COPYMATRIX_MB); + break; + case FN_InsertMatrixColumns: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(InsertMatrixColumn(INSERTMATRIXCOLUMNS_MA, INSERTMATRIXCOLUMNS_C, INSERTMATRIXCOLUMNS_NUM_COLS)); + else + { + ProcessQueueMatrixOp(FN_InsertMatrixColumns, INSERTMATRIXCOLUMNS_MA, INSERTMATRIXCOLUMNS_C, INSERTMATRIXCOLUMNS_NUM_COLS); + rc_push_num(1); + } + break; + case FN_InsertMatrixRows: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(InsertMatrixRow(INSERTMATRIXROWS_MA, INSERTMATRIXROWS_R, INSERTMATRIXROWS_NUM_ROWS)); + else + { + ProcessQueueMatrixOp(FN_InsertMatrixRows, INSERTMATRIXROWS_MA, INSERTMATRIXROWS_R, INSERTMATRIXROWS_NUM_ROWS); + rc_push_num(1); + } + break; + case FN_MultiplyMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(MultiplyMatrix(MULTIPLYMATRIX_MA, MULTIPLYMATRIX_MB, MULTIPLYMATRIX_MC)); + else + { + ProcessQueueMatrixOp(FN_MultiplyMatrix, MULTIPLYMATRIX_MA, MULTIPLYMATRIX_MB, MULTIPLYMATRIX_MC); + rc_push_num(1); + } + break; + case FN_CubeMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(CubeMatrix(CUBEMATRIX_MA, CUBEMATRIX_MB, rc_active_matrix_process)); + else + { + ProcessQueueMatrixOp(FN_CubeMatrix, CUBEMATRIX_MA, CUBEMATRIX_MB); + rc_push_num(1); + } + break; + case FN_DeleteMatrixColumns: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(DeleteMatrixColumns(DELETEMATRIXCOLUMNS_MA, DELETEMATRIXCOLUMNS_C, DELETEMATRIXCOLUMNS_NUM_COLS, rc_active_matrix_process)); + else + { + ProcessQueueMatrixOp(FN_DeleteMatrixColumns, DELETEMATRIXCOLUMNS_MA, DELETEMATRIXCOLUMNS_C, DELETEMATRIXCOLUMNS_NUM_COLS); + rc_push_num(1); + } + break; + case FN_DeleteMatrixRows: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(DeleteMatrixRows(DELETEMATRIXROWS_MA, DELETEMATRIXROWS_R, DELETEMATRIXROWS_NUM_ROWS)); + else + { + ProcessQueueMatrixOp(FN_DeleteMatrixRows, DELETEMATRIXROWS_MA, DELETEMATRIXROWS_R, DELETEMATRIXROWS_NUM_ROWS); + rc_push_num(1); + } + break; + case FN_ClearMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + ClearMatrix(CLEARMATRIX_MA); + else + ProcessQueueMatrixOp(FN_ClearMatrix, CLEARMATRIX_MA); + break; + case FN_ClearMatrixColumns: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(ClearMatrixColumns(CLEARMATRIXCOLUMNS_MA, CLEARMATRIXCOLUMNS_C, CLEARMATRIXCOLUMNS_NUM_COLS)); + else + { + ProcessQueueMatrixOp(FN_ClearMatrixColumns, CLEARMATRIXCOLUMNS_MA, CLEARMATRIXCOLUMNS_C, CLEARMATRIXCOLUMNS_NUM_COLS); + rc_push_num(1); + } + break; + case FN_ClearMatrixRows: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(ClearMatrixRows(CLEARMATRIXROWS_MA, CLEARMATRIXROWS_R, CLEARMATRIXROWS_NUM_ROWS)); + else + { + ProcessQueueMatrixOp(FN_ClearMatrixRows, CLEARMATRIXROWS_MA, CLEARMATRIXROWS_R, CLEARMATRIXROWS_NUM_ROWS); + rc_push_num(1); + } + break; + case FN_FillMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + FillMatrix(FILLMATRIX_MA, FILLMATRIX_V); + else + ProcessQueueMatrixOp(FN_FillMatrix, FILLMATRIX_MA, FILLMATRIX_V); + break; + case FN_FillMatrixColumns: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(FillMatrixColumns(FILLMATRIXCOLUMNS_MA, FILLMATRIXCOLUMNS_C, FILLMATRIXCOLUMNS_NUM_COLS, FILLMATRIXCOLUMNS_V)); + else + { + ProcessQueueMatrixOp(FN_FillMatrixColumns, FILLMATRIXCOLUMNS_MA, FILLMATRIXCOLUMNS_C, FILLMATRIXCOLUMNS_NUM_COLS, FILLMATRIXCOLUMNS_V); + rc_push_num(1); + } + break; + case FN_FillMatrixRows: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(FillMatrixRows(FILLMATRIXROWS_MA, FILLMATRIXROWS_R, FILLMATRIXROWS_NUM_ROWS, FILLMATRIXROWS_V)); + else + { + ProcessQueueMatrixOp(FN_FillMatrixRows, FILLMATRIXROWS_MA, FILLMATRIXROWS_R, FILLMATRIXROWS_NUM_ROWS, FILLMATRIXROWS_V); + rc_push_num(1); + } + break; + case FN_CopyMatrixColumns: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(GetMatrixColumns(COPYMATRIXCOLUMNS_MA, COPYMATRIXCOLUMNS_MB, COPYMATRIXCOLUMNS_C, COPYMATRIXCOLUMNS_NUM_COLS)); + else + { + ProcessQueueMatrixOp(FN_CopyMatrixColumns, COPYMATRIXCOLUMNS_MA, COPYMATRIXCOLUMNS_MB, COPYMATRIXCOLUMNS_C, COPYMATRIXCOLUMNS_NUM_COLS); + rc_push_num(1); + } + break; + case FN_CopyMatrixRows: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(GetMatrixRows(COPYMATRIXROWS_MA, COPYMATRIXROWS_MB, COPYMATRIXROWS_R, COPYMATRIXROWS_NUM_ROWS)); + else + { + ProcessQueueMatrixOp(FN_CopyMatrixRows, COPYMATRIXROWS_MA, COPYMATRIXROWS_MB, COPYMATRIXROWS_R, COPYMATRIXROWS_NUM_ROWS); + rc_push_num(1); + } + break; + case FN_IdentityMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + IdentityMatrix(IDENTITYMATRIX_MA, IDENTITYMATRIX_N); + else + ProcessQueueMatrixOp(FN_IdentityMatrix, IDENTITYMATRIX_MA, IDENTITYMATRIX_N); + break; + case FN_SolveMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(SolveMatrix(SOLVEMATRIX_MA, SOLVEMATRIX_MB, SOLVEMATRIX_MC)); + else + { + ProcessQueueMatrixOp(FN_SolveMatrix, SOLVEMATRIX_MA, SOLVEMATRIX_MB, SOLVEMATRIX_MC); + rc_push_num(1); + } + break; + + //MAIN THREAD ONLY + case FN_IsEqualMatrix: //Number Function + rc_push_num(IsEqualMatrix(ISEQUALMATRIX_MA, ISEQUALMATRIX_MB, ISEQUALMATRIX_TOLERANCE)); + break; + + //MAIN THREAD ONLY + case FN_Determinant: //Number Function + rc_push_num(Determinant(DETERMINANT_MA)); + break; + + case FN_AdjointMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(AdjointMatrix(ADJOINTMATRIX_MA, ADJOINTMATRIX_MB)); + else + { + ProcessQueueMatrixOp(FN_AdjointMatrix, ADJOINTMATRIX_MA, ADJOINTMATRIX_MB); + rc_push_num(1); + } + break; + case FN_InvertMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(InvertMatrix(INVERTMATRIX_MA, INVERTMATRIX_MB)); + else + { + ProcessQueueMatrixOp(FN_InvertMatrix, INVERTMATRIX_MA, INVERTMATRIX_MB); + rc_push_num(1); + } + break; + + //MAIN THREAD ONLY + case FN_MatrixFromBuffer: //Sub Procedure + MatrixFromBuffer(MATRIXFROMBUFFER_MA, MATRIXFROMBUFFER_R, MATRIXFROMBUFFER_C, &MATRIXFROMBUFFER_BUFFER); + break; + + //MAIN THREAD ONLY + case FN_GetMatrix: //Sub Procedure + BufferFromMatrix(&GETMATRIX_BUFFER, GETMATRIX_MA); + break; + + case FN_RandomizeMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + RandomizeMatrix(RANDOMIZEMATRIX_MA, RANDOMIZEMATRIX_VMIN, RANDOMIZEMATRIX_VMAX); + else + ProcessQueueMatrixOp(FN_RandomizeMatrix, RANDOMIZEMATRIX_MA, RANDOMIZEMATRIX_VMIN, RANDOMIZEMATRIX_VMAX); + break; + + //MAIN THREAD ONLY + case FN_MatrixValue: //Number Function + rc_push_num(MatrixValue(MATRIXVALUE_MA, MATRIXVALUE_R, MATRIXVALUE_C)); + break; + + case FN_SetMatrixValue: //Sub Procedure + if(rc_active_matrix_process < 0) + SetMatrixValue(SETMATRIXVALUE_MA, SETMATRIXVALUE_R, SETMATRIXVALUE_C, SETMATRIXVALUE_V); + else + ProcessQueueMatrixOp(FN_SetMatrixValue, SETMATRIXVALUE_MA, SETMATRIXVALUE_R, SETMATRIXVALUE_C, SETMATRIXVALUE_V); + break; + case FN_ScalarMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + ScalarMatrix(SCALARMATRIX_MA, SCALARMATRIX_MB, SCALARMATRIX_S_VALUE); + else + ProcessQueueMatrixOp(FN_ScalarMatrix, SCALARMATRIX_MA, SCALARMATRIX_MB, SCALARMATRIX_S_VALUE); + break; + case FN_ScalarMatrixColumns: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(ScalarMatrixColumns(SCALARMATRIXCOLUMNS_MA, SCALARMATRIXCOLUMNS_MB, SCALARMATRIXCOLUMNS_C, SCALARMATRIXCOLUMNS_NUM_COLS, SCALARMATRIXCOLUMNS_S_VALUE)); + else + { + ProcessQueueMatrixOp(FN_ScalarMatrixColumns, SCALARMATRIXCOLUMNS_MA, SCALARMATRIXCOLUMNS_MB, SCALARMATRIXCOLUMNS_C, SCALARMATRIXCOLUMNS_NUM_COLS, SCALARMATRIXCOLUMNS_S_VALUE); + rc_push_num(1); + } + break; + case FN_ScalarMatrixRows: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(ScalarMatrixRows(SCALARMATRIXROWS_MA, SCALARMATRIXROWS_MB, SCALARMATRIXROWS_R, SCALARMATRIXROWS_NUM_ROWS, SCALARMATRIXROWS_S_VALUE)); + else + { + ProcessQueueMatrixOp(FN_ScalarMatrixRows, SCALARMATRIXROWS_MA, SCALARMATRIXROWS_MB, SCALARMATRIXROWS_R, SCALARMATRIXROWS_NUM_ROWS, SCALARMATRIXROWS_S_VALUE); + rc_push_num(1); + } + break; + case FN_SquareMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(SquareMatrix(SQUAREMATRIX_MA, SQUAREMATRIX_MB)); + else + { + ProcessQueueMatrixOp(FN_SquareMatrix, SQUAREMATRIX_MA, SQUAREMATRIX_MB); + rc_push_num(1); + } + break; + case FN_SubMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + SubMatrix(SUBMATRIX_MA, SUBMATRIX_R, SUBMATRIX_C); + else + ProcessQueueMatrixOp(FN_SubMatrix, SUBMATRIX_MA, SUBMATRIX_R, SUBMATRIX_C); + break; + case FN_SubtractMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(SubtractMatrix(SUBTRACTMATRIX_MA, SUBTRACTMATRIX_MB, SUBTRACTMATRIX_MC)); + else + { + ProcessQueueMatrixOp(FN_SubtractMatrix, SUBTRACTMATRIX_MA, SUBTRACTMATRIX_MB, SUBTRACTMATRIX_MC); + rc_push_num(1); + } + break; + case FN_SwapMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + SwapMatrix(SWAPMATRIX_MA, SWAPMATRIX_MB, rc_active_matrix_process); + else + ProcessQueueMatrixOp(FN_SwapMatrix, SWAPMATRIX_MA, SWAPMATRIX_MB); + break; + case FN_SwapMatrixColumn: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(SwapMatrixColumn(SWAPMATRIXCOLUMN_MA, SWAPMATRIXCOLUMN_C1, SWAPMATRIXCOLUMN_C2)); + else + { + ProcessQueueMatrixOp(FN_SwapMatrixColumn, SWAPMATRIXCOLUMN_MA, SWAPMATRIXCOLUMN_C1, SWAPMATRIXCOLUMN_C2); + rc_push_num(1); + } + break; + case FN_SwapMatrixRow: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(SwapMatrixRow(SWAPMATRIXROW_MA, SWAPMATRIXROW_R1, SWAPMATRIXROW_R2)); + else + { + ProcessQueueMatrixOp(FN_SwapMatrixRow, SWAPMATRIXROW_MA, SWAPMATRIXROW_R1, SWAPMATRIXROW_R2); + rc_push_num(1); + } + break; + case FN_TransposeMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(TransposeMatrix(TRANSPOSEMATRIX_MA, TRANSPOSEMATRIX_MB)); + else + { + ProcessQueueMatrixOp(FN_TransposeMatrix, TRANSPOSEMATRIX_MA, TRANSPOSEMATRIX_MB); + rc_push_num(1); + } + break; + case FN_UnAugmentMatrix: //Number Function + if(rc_active_matrix_process < 0) + rc_push_num(UnAugmentMatrix(UNAUGMENTMATRIX_MA, UNAUGMENTMATRIX_MB, UNAUGMENTMATRIX_MC)); + else + { + ProcessQueueMatrixOp(FN_UnAugmentMatrix, UNAUGMENTMATRIX_MA, UNAUGMENTMATRIX_MB, UNAUGMENTMATRIX_MC); + rc_push_num(1); + } + break; + case FN_ZeroMatrix: //Sub Procedure + if(rc_active_matrix_process < 0) + ZeroMatrix(ZEROMATRIX_MA); + else + ProcessQueueMatrixOp(FN_ZeroMatrix, ZEROMATRIX_MA); + break; + + //MAIN THREAD ONLY + case FN_GetMatrixSize: //Sub Procedure + GetMatrixSize(GETMATRIXSIZE_MA, &GETMATRIXSIZE_R, &GETMATRIXSIZE_C); + break; + + case FN_SetMatrixProcess: //Number Function + rc_push_num(rc_setMatrixProcess(SETMATRIXPROCESS_P_NUM)); + break; + case FN_ProcessOpen: //Number Function + rc_push_num(rc_processOpen(PROCESSOPEN_P_NUM)); + break; + case FN_SetProcessErrorMode: //Sub Procedure + rc_setProcessErrorMode(SETPROCESSERRORMODE_P_NUM, SETPROCESSERRORMODE_ERROR_MODE); + break; + case FN_ProcessError: //Number Function + rc_push_num(ProcessError(PROCESSERROR_P_NUM)); + break; + case FN_ProcessWait: //Sub Procedure + ProcessWait(PROCESSWAIT_P_NUM); + break; + case FN_ProcessWaitAll: //Sub Procedure + ProcessWaitAll(); + break; + case FN_ProcessContinue: //Sub Procedure + ProcessContinue(PROCESSCONTINUE_P_NUM); + break; + case FN_ProcessStop: //Sub Procedure + ProcessStop(PROCESSSTOP_P_NUM); + break; + case FN_ProcessClear: //Sub Procedure + ProcessClear(PROCESSCLEAR_P_NUM); + break; + case FN_ProcessClose: //Number Function + rc_push_num(ProcessClose(PROCESSCLOSE_P_NUM)); + break; + case FN_ProcessErrorMode: //Number Function + rc_push_num(ProcessErrorMode(PROCESSERRORMODE_P_NUM)); + break; + case FN_ProcessSleep: //Sub Procedure + ProcessSleep(PROCESSSLEEP_P_NUM, PROCESSSLEEP_MSEC); + break; + case FN_ProcessExists: //Number Function + rc_push_num(ProcessExists(PROCESSEXISTS_P_NUM)); + break; + case FN_ProcessStopAll: //Sub Procedure + ProcessStopAll(); + break; + case FN_ProcessContinueAll: //Sub Procedure + ProcessContinueAll(); + break; + case FN_ProcessQueueSize: //Number Function + rc_push_num(ProcessQueueSize(PROCESSQUEUESIZE_P_NUM)); + break; + case FN_NumCPUs: //Number Function + rc_push_num(NumCPUs()); + break; + case FN_GetProjectionGeometry: //Sub Procedure + rc_GetProjectionGeometry(GETPROJECTIONGEOMETRY_CAM_DIST, GETPROJECTIONGEOMETRY_MA, GETPROJECTIONGEOMETRY_F_VERTEX_COUNT, &GETPROJECTIONGEOMETRY_COLUMNS, &GETPROJECTIONGEOMETRY_UV, + GETPROJECTIONGEOMETRY_GRAPH_OFFSET_X, GETPROJECTIONGEOMETRY_GRAPH_OFFSET_Y, GETPROJECTIONGEOMETRY_V_COLOR, + &GETPROJECTIONGEOMETRY_VERTEX_COUNT, &GETPROJECTIONGEOMETRY_VERTEX2D, &GETPROJECTIONGEOMETRY_INDEX_COUNT, &GETPROJECTIONGEOMETRY_INDEX, + &GETPROJECTIONGEOMETRY_CLIP_DIST, &GETPROJECTIONGEOMETRY_MIN_X, &GETPROJECTIONGEOMETRY_MIN_Y, &GETPROJECTIONGEOMETRY_MAX_X, &GETPROJECTIONGEOMETRY_MAX_Y); + break; + case FN_CalculateFaceZ: //Number Function + rc_push_num( CalculateFaceZ(CALCULATEFACEZ_CAM_DIST, CALCULATEFACEZ_GRAPH_OFFSET_X, CALCULATEFACEZ_GRAPH_OFFSET_Y, CALCULATEFACEZ_VIEW_W, CALCULATEFACEZ_VIEW_H, CALCULATEFACEZ_VIEW_DEPTH, + CALCULATEFACEZ_MA, CALCULATEFACEZ_F_VERTEX_COUNT, &CALCULATEFACEZ_COLUMNS, &CALCULATEFACEZ_FACE_MIN_Z, &CALCULATEFACEZ_FACE_MAX_Z, &CALCULATEFACEZ_Z_AVG)); + break; + case FN_SetChannelSpacePosition: //Number Function + rc_push_num(rc_media_setChannelSpacePosition(SETCHANNELSPACEPOSITION_CHANNEL, SETCHANNELSPACEPOSITION_ANGLE, SETCHANNELSPACEPOSITION_DISTANCE)); + break; + case FN_SaveBMP: //Number Function + rc_push_num(SaveBMP(SAVEBMP_IMG, SAVEBMP_FILE$)); + break; + case FN_SavePNG: //Number Function + rc_push_num(SavePNG(SAVEPNG_IMG, SAVEPNG_FILE$)); + break; + case FN_SaveJPG: //Number Function + rc_push_num(SaveJPG(SAVEJPG_IMG, SAVEJPG_FILE$)); + break; + case FN_GetLineIntersection: //Number Function + rc_push_num(GetLineIntersect(GETLINEINTERSECTION_P0_X, GETLINEINTERSECTION_P0_Y, + GETLINEINTERSECTION_P1_X, GETLINEINTERSECTION_P1_Y, + GETLINEINTERSECTION_P2_X, GETLINEINTERSECTION_P2_Y, + GETLINEINTERSECTION_P3_X, GETLINEINTERSECTION_P3_Y, + &GETLINEINTERSECTION_I_X, &GETLINEINTERSECTION_I_Y)); + break; + case FN_Interpolate: //Number Function + rc_push_num(Interpolate(INTERPOLATE_MIN_A, INTERPOLATE_MAX_A, INTERPOLATE_MID_A, INTERPOLATE_MIN_B, INTERPOLATE_MAX_B)); + break; + case FN_ATan2: //Number Function + rc_push_num(atan2(ATAN2_Y, ATAN2_X)); + break; + case FN_PointInQuad: //Number Function + rc_push_num(PointInQuad(POINTINQUAD_X, POINTINQUAD_Y, + POINTINQUAD_X1, POINTINQUAD_Y1, + POINTINQUAD_X2, POINTINQUAD_Y2, + POINTINQUAD_X3, POINTINQUAD_Y3, + POINTINQUAD_X4, POINTINQUAD_Y4)); + break; + case FN_PointInTri: //Number Function + rc_push_num(PointInTri(POINTINTRI_X, POINTINTRI_Y, + POINTINTRI_X1, POINTINTRI_Y1, + POINTINTRI_X2, POINTINTRI_Y2, + POINTINTRI_X3, POINTINTRI_Y3)); + break; + case FN_Distance2D: //Number Function + rc_push_num(Distance2D(DISTANCE2D_X1, DISTANCE2D_Y1, DISTANCE2D_X2, DISTANCE2D_Y2)); + break; + case FN_Distance3D: //Number Function + rc_push_num(Distance3D(DISTANCE3D_X1, DISTANCE3D_Y1, DISTANCE3D_Z1, DISTANCE3D_X2, DISTANCE3D_Y2, DISTANCE3D_Z2)); + break; + case FN_GetCircleLineIntersection: //Number Function + rc_push_num(GetCircleLineIntersection(GETCIRCLELINEINTERSECTION_CIRCLE_X, GETCIRCLELINEINTERSECTION_CIRCLE_Y, GETCIRCLELINEINTERSECTION_RADIUS, + GETCIRCLELINEINTERSECTION_X1, GETCIRCLELINEINTERSECTION_Y1, + GETCIRCLELINEINTERSECTION_X2, GETCIRCLELINEINTERSECTION_Y2, + &GETCIRCLELINEINTERSECTION_IX1, &GETCIRCLELINEINTERSECTION_IY1, + &GETCIRCLELINEINTERSECTION_IX2, &GETCIRCLELINEINTERSECTION_IY2)); + break; + case FN_GetLinePlaneIntersection: //Number Function + rc_push_num(GetLinePlaneIntersection(&GETLINEPLANEINTERSECTION_LINE_POINT, &GETLINEPLANEINTERSECTION_LINE_DIRECTION, + &GETLINEPLANEINTERSECTION_PLANE_POINT_1, + &GETLINEPLANEINTERSECTION_PLANE_POINT_2, + &GETLINEPLANEINTERSECTION_PLANE_POINT_3, + &GETLINEPLANEINTERSECTION_INTERSECTION)); + break; + case FN_IncrementMatrixRows: //Sub Procedure + IncrementMatrixRows(INCREMENTMATRIXROWS_MA, INCREMENTMATRIXROWS_MB, INCREMENTMATRIXROWS_R, INCREMENTMATRIXROWS_NUM_ROWS, INCREMENTMATRIXROWS_VALUE); + break; + case FN_IncrementMatrixColumns: //Sub Procedure + IncrementMatrixColumns(INCREMENTMATRIXCOLUMNS_MA, INCREMENTMATRIXCOLUMNS_MB, INCREMENTMATRIXCOLUMNS_C, INCREMENTMATRIXCOLUMNS_NUM_COLS, INCREMENTMATRIXCOLUMNS_VALUE); + break; + case FN_JoinMatrixRows: //Sub Procedure + JoinMatrixRows(JOINMATRIXROWS_MA, JOINMATRIXROWS_MB, JOINMATRIXROWS_MC); + break; + case FN_JoinMatrixColumns: //Sub Procedure + JoinMatrixColumns(JOINMATRIXCOLUMNS_MA, JOINMATRIXCOLUMNS_MB, JOINMATRIXCOLUMNS_MC); + break; + + + } +} + +void push_131(double num) +{ + rc_vm_n tmp_n; + tmp_n.value = num; + n_stack.push(tmp_n); + //current_n_stack_count++; +} + +void println_132() +{ + cout << endl; +} + +void mov_133(int n1, int flag) +{ + switch(flag) + { + case LESS_FLAG: + vm_n[n1].value = CMP_FLAG_LESS; + break; + case LESS_EQUAL_FLAG: + vm_n[n1].value = CMP_FLAG_LESS_EQUAL; + break; + case GREATER_FLAG: + vm_n[n1].value = CMP_FLAG_GREATER; + break; + case GREATER_EQUAL_FLAG: + vm_n[n1].value = CMP_FLAG_GREATER_EQUAL; + break; + case EQUAL_FLAG: + vm_n[n1].value = CMP_FLAG_EQUAL; + break; + case NOT_EQUAL_FLAG: + vm_n[n1].value = CMP_FLAG_NOT_EQUAL; + break; + } + //cout << "n" << n1 << " = " << vm_n[n1].value << endl; +} + +void cmp_134(int n1, double num) +{ + CMP_FLAG_EQUAL = (vm_n[n1].value == num); + CMP_FLAG_GREATER = (vm_n[n1].value > num); + CMP_FLAG_GREATER_EQUAL = (vm_n[n1].value >= num); + CMP_FLAG_LESS = (vm_n[n1].value < num); + CMP_FLAG_LESS_EQUAL = (vm_n[n1].value <= num); + CMP_FLAG_NOT_EQUAL = (vm_n[n1].value != num); +} + +void mov_arr_135(int n1, uint64_t nid) +{ + arr_ref_id.push_back( nid ); + vm_n[n1].r = num_var[nid].nref; +} + +void mov_arrS_136(int s1, uint64_t sid) +{ + arr_ref_id.push_back( sid ); + vm_s[s1].r = str_var[sid].sref; +} + +void pop_ptr_137(uint64_t n) +{ + //cout << "pop_ptr " << n << endl; + //cout << "b_stack_size = " << byref_addr_table.size() << endl; + for(int i = 0; i < n; i++) + { + //cout << "byref i = " << i << endl; + switch(byref_addr_table.top().type) + { + case BYREF_TYPE_NUM: + num_var[byref_addr_table.top().ptr_id].nref = (n_value*)byref_addr_table.top().ptr_addr; + num_var[byref_addr_table.top().ptr_id].byref_offset = byref_var_byref_offset.top(); + break; + case BYREF_TYPE_STR: + str_var[byref_addr_table.top().ptr_id].sref = (s_value*)byref_addr_table.top().ptr_addr; + str_var[byref_addr_table.top().ptr_id].byref_offset = byref_var_byref_offset.top(); + break; + case BYREF_TYPE_USR: + usr_var[byref_addr_table.top().ptr_id].var_ref = (rc_usrId*)byref_addr_table.top().ptr_addr; + usr_var[byref_addr_table.top().ptr_id].var_ref_index = byref_var_byref_offset.top(); + break; + } + byref_addr_table.pop(); + byref_var_byref_offset.pop(); + } +} + +void preset_138(uint64_t nid) +{ + int nid_size = 1; + switch(num_var[nid].dimensions) + { + case 3: + nid_size *= num_var[nid].dim[2]; + case 2: + nid_size *= num_var[nid].dim[1]; + case 1: + nid_size *= num_var[nid].dim[0]; + break; + } + for(int i = 0; i < nid_size; i++) + num_var[nid].nref[0].value[i] = 0; +} + +void presetS_139(uint64_t sid) +{ + int sid_size = 1; + switch(str_var[sid].dimensions) + { + case 3: + sid_size *= str_var[sid].dim[2]; + case 2: + sid_size *= str_var[sid].dim[1]; + case 1: + sid_size *= str_var[sid].dim[0]; + break; + } + for(int i = 0; i < sid_size; i++) + str_var[sid].sref[0].value[i] = ""; +} + +void redim_140(uint64_t nid, int n1) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_REDIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + num_var[nid].nref[0].value.resize((uint64_t)vm_n[n1].value); + num_var[nid].dimensions = 1; + num_var[nid].dim[0] = (uint64_t)vm_n[n1].value; + num_var[nid].dim[1] = 0; + num_var[nid].dim[2] = 0; +} + +void redim_141(uint64_t nid, int n1, int n2) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_REDIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + num_var[nid].nref[0].value.resize( (uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value ); + num_var[nid].dimensions = 2; + num_var[nid].dim[0] = (uint64_t)vm_n[n1].value; + num_var[nid].dim[1] = (uint64_t)vm_n[n2].value; + num_var[nid].dim[2] = 0; +} + +void redim_142(uint64_t nid, int n1, int n2, int n3) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0 || vm_n[n3].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_REDIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + num_var[nid].nref[0].value.resize( (uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value * (uint64_t)vm_n[n3].value); + num_var[nid].dimensions = 3; + num_var[nid].dim[0] = (uint64_t)vm_n[n1].value; + num_var[nid].dim[1] = (uint64_t)vm_n[n2].value; + num_var[nid].dim[2] = (uint64_t)vm_n[n3].value; +} + +void redimS_143(uint64_t sid, int n1) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_REDIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + str_var[sid].sref[0].value.resize((uint64_t)vm_n[n1].value); + str_var[sid].dimensions = 1; + str_var[sid].dim[0] = (uint64_t)vm_n[n1].value; + str_var[sid].dim[1] = 0; + str_var[sid].dim[2] = 0; +} + +void redimS_144(uint64_t sid, int n1, int n2) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_REDIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + str_var[sid].sref[0].value.resize( (uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value ); + str_var[sid].dimensions = 2; + str_var[sid].dim[0] = (uint64_t)vm_n[n1].value; + str_var[sid].dim[1] = (uint64_t)vm_n[n2].value; + str_var[sid].dim[2] = 0; +} + +void redimS_145(uint64_t sid, int n1, int n2, int n3) +{ + #ifdef RCBASIC_DEBUG + if(vm_n[n1].value <= 0 || vm_n[n2].value <= 0 || vm_n[n3].value <= 0) + { + dbg_error_found = true; + dbg_error_message = DBG_REDIM_LEQ_ZERO; + return; + } + #endif // RCBASIC_DEBUG + str_var[sid].sref[0].value.resize( (uint64_t)vm_n[n1].value * (uint64_t)vm_n[n2].value * (uint64_t)vm_n[n3].value); + str_var[sid].dimensions = 3; + str_var[sid].dim[0] = (uint64_t)vm_n[n1].value; + str_var[sid].dim[1] = (uint64_t)vm_n[n2].value; + str_var[sid].dim[2] = (uint64_t)vm_n[n3].value; +} + +void for_offset_arr1_146(int n1) +{ + for_offset_index[0] = vm_n[n1].value; + for_offset_dimensions = 1; +} + +void for_offset_arr2_147(int n1, int n2) +{ + for_offset_index[0] = vm_n[n1].value; + for_offset_index[1] = vm_n[n2].value; + for_offset_dimensions = 2; +} + +void for_offset_arr3_148(int n1, int n2, int n3) +{ + for_offset_index[0] = vm_n[n1].value; + for_offset_index[1] = vm_n[n2].value; + for_offset_index[2] = vm_n[n3].value; + for_offset_dimensions = 3; +} + +void for_offset_0_149() +{ + for_offset_dimensions = 0; +} + +void end_x_150(int n1) +{ + rcbasic_exit_code = (int)vm_n[n1].value; +} + +void lval_151(int n1) +{ + //cout << "lval_151 = " << vm_n[n1].value << endl; +} + +void lval_152(uint64_t nid) +{ + //cout << "lval_152 = " << num_var[nid].nid_value[0].value[0] << endl; +} + +void lval_153(uint64_t lval_addr ) +{ + //cout << "lval_153 = " << lval_addr << endl; +} + +void lval_154(int s1) +{ + //cout << "lval_154 = " << vm_s[s1].value << endl; +} + +void lval_155(uint64_t sid) +{ + //cout << "lval_155 = " << str_var[sid].sid_value[0].value[0] << endl; +} + +void obj_usr_n_156(uint64_t nid) +{ + //cout << "obj_usr_n start" << endl; + usr_object.num_ref = &usr_object.obj_ref->num_var[nid]; + usr_object.num_ref->nref = &usr_object.num_ref->nid_value; + usr_object.index = 0; + //cout << "obj_usr_n done" << endl; +} + +void obj_usr_n1_157(uint64_t nid, int n1) +{ + usr_object.num_ref = &usr_object.obj_ref->num_var[nid]; + usr_object.num_ref->nref = &usr_object.num_ref->nid_value; + usr_object.index = (uint64_t)vm_n[n1].value; +} + +void obj_usr_n2_158(uint64_t nid, int n1, int n2) +{ + usr_object.num_ref = &usr_object.obj_ref->num_var[nid]; + usr_object.num_ref->nref = &usr_object.num_ref->nid_value; + usr_object.index = (uint64_t)vm_n[n1].value * usr_object.num_ref->dim[1] + (uint64_t)vm_n[n2].value; +} + +void obj_usr_n3_159(uint64_t nid, int n1, int n2, int n3) +{ + usr_object.num_ref = &usr_object.obj_ref->num_var[nid]; + usr_object.num_ref->nref = &usr_object.num_ref->nid_value; + usr_object.index = ((uint64_t)vm_n[n1].value * usr_object.num_ref->dim[1] * usr_object.num_ref->dim[2]) + ( (uint64_t)vm_n[n2].value * usr_object.num_ref->dim[2]) + (uint64_t)vm_n[n3].value; +} + + +void obj_usr_s_160(uint64_t sid) +{ + usr_object.str_ref = &usr_object.obj_ref->str_var[sid]; + usr_object.str_ref->sref = &usr_object.str_ref->sid_value; + usr_object.index = 0; +} + +void obj_usr_s1_161(uint64_t sid, int n1) +{ + usr_object.str_ref = &usr_object.obj_ref->str_var[sid]; + usr_object.str_ref->sref = &usr_object.str_ref->sid_value; + usr_object.index = (uint64_t)vm_n[n1].value; +} + +void obj_usr_s2_162(uint64_t sid, int n1, int n2) +{ + usr_object.str_ref = &usr_object.obj_ref->str_var[sid]; + usr_object.str_ref->sref = &usr_object.str_ref->sid_value; + usr_object.index = (uint64_t)vm_n[n1].value * usr_object.str_ref->dim[1] + (uint64_t)vm_n[n2].value; +} + +void obj_usr_s3_163(uint64_t sid, int n1, int n2, int n3) +{ + usr_object.str_ref = &usr_object.obj_ref->str_var[sid]; + usr_object.str_ref->sref = &usr_object.str_ref->sid_value; + usr_object.index = ((uint64_t)vm_n[n1].value * usr_object.str_ref->dim[1] * usr_object.str_ref->dim[2]) + ( (uint64_t)vm_n[n2].value * usr_object.str_ref->dim[2]) + (uint64_t)vm_n[n3].value; +} + +void obj_usr_get_164(int n1) +{ + //cout << "obj_usr_get_N start" << endl; + vm_n[n1].value = usr_object.num_ref->nref[0].value[usr_object.index]; + vm_n[n1].r = usr_object.num_ref->nref; + vm_n[n1].r_index = usr_object.index; + //cout << "obj_usr_get_N done: " << vm_n[n1].r[0].value[vm_n[n1].r_index] << endl; +} + +void obj_usr_get_165(int s1) +{ + vm_s[s1].value = usr_object.str_ref->sref[0].value[usr_object.index]; + vm_s[s1].r = usr_object.str_ref->sref; + vm_s[s1].r_index = usr_object.index; +} + +void obj_usr_get_166(int u1) +{ + //cout << "obj_usr_get start u" << u1 << endl; + rc_free_type(&vm_u[u1]); //this should free any memory previously allocated in u1 + //cout << "mem free: " << usr_object.obj_ref->dimensions << endl; + vm_u[u1] = usr_object.obj_ref[0]; + //cout << "1: " << usr_object.obj_ref[0].uid_value.size() << endl; + vm_u[u1].var_ref = usr_object.obj_ref; + //cout << "2" << endl; + vm_u[u1].var_ref_index = 0 ; //usr_object.index; This has become unnecessary because var_ref points to the correct index + //cout << "obj_usr_get end" << endl; +} + +void uref_ptr_167(uint64_t uid, int u1) +{ + //cout << "<--------UREF-------> : " << uid << " " << u1 << endl; + byref_id.ptr_id = uid; + byref_id.ptr_addr = usr_var[uid].var_ref; + byref_id.type = BYREF_TYPE_USR; + byref_addr_table.push(byref_id); + byref_var_byref_offset.push(usr_var[uid].var_ref_index); + + usr_var[uid].var_ref = vm_u[u1].var_ref; + usr_var[uid].var_ref_index = vm_u[u1].var_ref_index; +} + +void mov_type_168(uint64_t uid, int u1) +{ + //cout << "mov_type " << uid << " " << u1 << endl; + //cout << "dbg[var_ref] : " << vm_u[u1].var_ref[0].uid_value.size() << endl; + rc_free_type(&usr_var[uid]); + //usr_var[uid].uid_value.resize(1); + //cout << "dbg[usr_var]: " << usr_var[uid].uid_value.size() << endl; + usr_var[uid].uid_value.push_back(vm_u[u1]); + usr_var[uid].var_ref = &usr_var[uid]; + usr_var[uid].var_ref_index = 0; + //cout << "mov_type end" << endl; +} + +void push_t_169(int u1) +{ + //cout << "push_t u" << u1 << " :: " << vm_u[u1].uid_value.size() << endl; + u_stack.push(vm_u[u1]); + //cout << "push_t end" << endl; +} + +void push_t_170(uint64_t uid) +{ + u_stack.push(usr_var[uid]); +} + +void pop_t_171(int u1) +{ + //cout << "pop_t u" << u1 << " :: " << vm_u[u1].uid_value.size() << endl; + rc_free_type(&vm_u[u1]); + vm_u[u1] = u_stack.top(); + //cout << "test: " << vm_u[u1].var_ref->uid_value.size() << endl; + u_stack.pop(); +} + +void pop_t_172(uint64_t uid) +{ + //cout << "pop_T USER" << endl; + rc_free_type(usr_var[uid].var_ref); + usr_var[uid].var_ref[0] = u_stack.top(); + u_stack.pop(); +} + +void push_t_null_173() +{ + //I will need to do something with this +} + +void delete_t_174(uint64_t uid) +{ + rc_free_type(&usr_object.obj_ref->uid_value[uid]); +} + +void dim_type_175(int u1, int udt_index) +{ + rc_free_type(&vm_u[u1]); + rc_dim_type(&vm_u[u1], udt_index, 0, 0, 0, 0 ); +} + +void dim_type1_176(int u1, int udt_index, int n1) +{ + rc_free_type(&vm_u[u1]); + rc_dim_type(&vm_u[u1], udt_index, 1, (uint64_t)vm_n[n1].value, 0, 0 ); +} + +void dim_type2_177(int u1, int udt_index, int n1, int n2) +{ + rc_free_type(&vm_u[u1]); + rc_dim_type(&vm_u[u1], udt_index, 2, (uint64_t)vm_n[n1].value, (uint64_t)vm_n[n2].value, 0 ); +} + +void dim_type3_178(int u1, int udt_index, int n1, int n2, int n3) +{ + rc_free_type(&vm_u[u1]); + rc_dim_type(&vm_u[u1], udt_index, 3, (uint64_t)vm_n[n1].value, (uint64_t)vm_n[n2].value, (uint64_t)vm_n[n3].value ); +} + +void dim_tfield_179(uint64_t udt_index, uint64_t field_type, uint64_t field_index, int num_dim, int n1, int n2, int n3) +{ + //cout << "DimTField " << udt_index << " " << field_type << " " << field_index << " " << num_dim << " " << (uint64_t)vm_n[n1].value << " " << (uint64_t)vm_n[n2].value << " " << (uint64_t)vm_n[n3].value << endl; + rc_types[udt_index].field_dimensions[field_index] = num_dim; + rc_types[udt_index].field_size[field_index].dim[0] = (uint64_t)vm_n[n1].value; + rc_types[udt_index].field_size[field_index].dim[1] = (uint64_t)vm_n[n2].value; + rc_types[udt_index].field_size[field_index].dim[2] = (uint64_t)vm_n[n3].value; + //cout << "DimTField End" << endl; +} + +void obj_usr_init_180(uint64_t uid) +{ + //cout << "obj_usr_init " << uid << endl; + usr_object.index = 0; + usr_object.obj_ref = &usr_var[uid].var_ref->uid_value[usr_object.index]; //need to switch to var_ref + //cout << "obj_usr_init done: " << usr_object.obj_ref[0].uid_value.size() << endl; +} + +void obj_usr_init1_181(uint64_t uid, int n1) +{ + //cout << "obj_usr_init1 " << uid << endl; + usr_object.index = (uint64_t)vm_n[n1].value; + usr_object.obj_ref = &usr_var[uid].var_ref->uid_value[usr_object.index]; +} + +void obj_usr_init2_182(uint64_t uid, int n1, int n2) +{ + //uint64_t d[3]; + //d[0] = usr_var[uid].dim[0]; + //d[1] = usr_var[uid].dim[1]; + //d[2] = usr_var[uid].dim[2]; + //cout << "obj_usr_init2: " << uid << " --dim=[" << d[0] << ", " << d[1] << ", " << d[2] << "]" << endl; + usr_object.index = (uint64_t)vm_n[n1].value * usr_var[uid].dim[1] + (uint64_t)vm_n[n2].value; + usr_object.obj_ref = &usr_var[uid].var_ref->uid_value[usr_object.index]; +} + +void obj_usr_init3_183(uint64_t uid, int n1, int n2, int n3) +{ + //cout << "obj_usr_init3 " << uid << endl; + usr_object.index = ( (uint64_t)vm_n[n1].value * usr_var[uid].dim[1] * usr_var[uid].dim[2] ) + ((uint64_t)vm_n[n2].value * usr_var[uid].dim[2]) + (uint64_t)vm_n[n3].value;; + usr_object.obj_ref = &usr_var[uid].var_ref->uid_value[usr_object.index]; +} + + +void obj_usr_init_184(int u1) +{ + //cout << "obj_usr_init u" << u1 << endl; + usr_object.index = 0; + usr_object.obj_ref = &vm_u[u1]; //need to switch to var_ref + usr_object.obj_ref->var_ref = usr_object.obj_ref; + //cout << "obj_usr_init done: " << usr_object.obj_ref->var_ref[0].uid_value.size() << " ~ " << vm_u[u1].uid_value.size() << endl; +} + +void obj_usr_init1_185(int u1, int n1) +{ + //cout << "obj_usr_init1 u" << u1 << endl; + usr_object.index = (uint64_t)vm_n[n1].value; + usr_object.obj_ref = &vm_u[u1].var_ref->uid_value[usr_object.index]; +} + +void obj_usr_init2_186(int u1, int n1, int n2) +{ + uint64_t d[3]; + //cout << "obj_usr_init2: u" << u1 << " --dim=[" << d[0] << ", " << d[1] << ", " << d[2] << "]" << endl; + usr_object.index = (uint64_t)vm_n[n1].value * vm_u[u1].dim[1] + (uint64_t)vm_n[n2].value; + usr_object.obj_ref = &vm_u[u1].var_ref->uid_value[usr_object.index]; +} + +void obj_usr_init3_187(int u1, int n1, int n2, int n3) +{ + //cout << "obj_usr_init3 u" << u1 << endl; + usr_object.index = ( (uint64_t)vm_n[n1].value * vm_u[u1].dim[1] * vm_u[u1].dim[2] ) + ((uint64_t)vm_n[n2].value * vm_u[u1].dim[2]) + (uint64_t)vm_n[n3].value;; + usr_object.obj_ref = &vm_u[u1].var_ref->uid_value[usr_object.index]; +} + + + + + +bool rc_preset_type(rc_usrId* parent) +{ + uint64_t dim_size = parent->uid_value.size(); + + + rc_usrId* p_obj; + + uint64_t field_size = 0; + + for(uint64_t i = 0; i < dim_size; i++) + { + p_obj = &parent->uid_value[i]; + + for(uint64_t n_field = 0; n_field < p_obj->num_var.size(); n_field++) + { + for(uint64_t nv = 0; nv < p_obj->num_var[n_field].nid_value.value.size(); nv++) + p_obj->num_var[n_field].nid_value.value[nv] = 0; + } + + for(uint64_t s_field = 0; s_field < p_obj->str_var.size(); s_field++) + { + for(uint64_t sv = 0; sv < p_obj->str_var[s_field].sid_value.value.size(); sv++) + p_obj->str_var[s_field].sid_value.value[sv] = ""; + } + + for(uint64_t u_field = 0; u_field < p_obj->uid_value.size(); u_field++) + { + rc_preset_type(&p_obj->uid_value[u_field]); + } + } + + return true; +} + +void preset_t_188(uint64_t uid, uint64_t utype) +{ + //cout << "T0" << endl; + if(!usr_var[uid].preset_init) + { + rc_free_type(&usr_var[uid]); + dim_type_90(uid, utype); + usr_var[uid].preset_init = true; + } + else + { + rc_preset_type(&usr_var[uid]); + } +} + +void preset_t1_189(uint64_t uid, uint64_t utype, int n1) +{ + //cout << "T1" << endl; + if(!usr_var[uid].preset_init) + { + rc_free_type(&usr_var[uid]); + dim_type1_91(uid, utype, n1); + usr_var[uid].preset_init = true; + } + else + { + rc_preset_type(&usr_var[uid]); + } +} + +void preset_t2_190(uint64_t uid, uint64_t utype, int n1, int n2) +{ + //cout << "T2" << endl; + if(!usr_var[uid].preset_init) + { + rc_free_type(&usr_var[uid]); + dim_type2_92(uid, utype, n1, n2); + usr_var[uid].preset_init = true; + } + else + { + rc_preset_type(&usr_var[uid]); + } +} + +void preset_t3_191(uint64_t uid, uint64_t utype, int n1, int n2, int n3) +{ + //cout << "T3" << endl; + if(!usr_var[uid].preset_init) + { + rc_free_type(&usr_var[uid]); + dim_type3_93(uid, utype, n1, n2, n3); + usr_var[uid].preset_init = true; + } + else + { + rc_preset_type(&usr_var[uid]); + } +} + +bool rcbasic_run() +{ + unsigned char rcbasic_cmd; + double d[12]; + uint64_t i[12]; + bool end_of_program = false; + while(!end_of_program) + { + #ifdef RCBASIC_DEBUG + if(dbg_error_found) + { + output_debug_message(); + break; + } + #endif // RCBASIC_DEBUG + + rcbasic_cmd = segment[current_segment][current_address]; + current_address++; + + //cout << "n3 = " << vm_n[3].value << endl; + //cout << "x = " << num_var[0].value[0] << endl; + //cout << "\ncmd = " << (int)rcbasic_cmd << endl; + + switch(rcbasic_cmd) + { + case 0: + end_of_program = true; + rcbasic_exit_code = 0; + break; + case 1: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + dbg_1(i[0], i[1], i[2]); + break; + case 32: + i[0] = readInt(); + i[1] = readInt(); + mov_32(i[0], i[1]); + break; + case 33: + i[0] = readInt(); + d[0] = readDouble(); + mov_33(i[0], d[0]); + break; + case 34: + i[0] = readInt(); + i[1] = readInt(); + mov_34(i[0], i[1]); + break; + case 35: + i[0] = readInt(); + i[1] = readInt(); + //cout << "mov_35 x is " << i[0] << endl; + //cout << "mov_35 is using n" << i[1] << endl; + mov_35(i[0], i[1]); + break; + case 36: + i[0] = readInt(); + i[1] = readInt(); + movS_36(i[0], i[1]); + break; + case 37: + i[0] = readInt(); + i[1] = readInt(); + movS_37(i[0], i[1]); + break; + case 38: + i[0] = readInt(); + i[1] = readInt(); + movS_38(i[0], i[1]); + break; + case 39: + i[0] = readInt(); + i[1] = readInt(); + movS_39(i[0], i[1]); + break; + case 40: + i[0] = readInt(); + i[1] = readInt(); + mov_r_40(i[0], i[1]); + break; + case 41: + i[0] = readInt(); + i[1] = readInt(); + mov_rS_41(i[0], i[1]); + break; + case 42: + i[0] = readInt(); + i[1] = readInt(); + mov_type_42(i[0], i[1]); + break; + case 43: + i[0] = readInt(); + i[1] = readInt(); + addS_43(i[0], i[1]); + break; + case 44: + i[0] = readInt(); + i[1] = readInt(); + add_44(i[0], i[1]); + break; + case 45: + i[0] = readInt(); + i[1] = readInt(); + sub_45(i[0], i[1]); + break; + case 46: + i[0] = readInt(); + i[1] = readInt(); + mul_46(i[0], i[1]); + break; + case 47: + i[0] = readInt(); + i[1] = readInt(); + div_47(i[0], i[1]); + break; + case 48: + i[0] = readInt(); + i[1] = readInt(); + pow_48(i[0], i[1]); + break; + case 49: + i[0] = readInt(); + i[1] = readInt(); + mod_49(i[0], i[1]); + break; + case 50: + i[0] = readInt(); + i[1] = readInt(); + shl_50(i[0], i[1]); + break; + case 51: + i[0] = readInt(); + i[1] = readInt(); + shr_51(i[0], i[1]); + break; + case 52: + i[0] = readInt(); + i[1] = readInt(); + and_52(i[0], i[1]); + break; + case 53: + i[0] = readInt(); + i[1] = readInt(); + or_53(i[0], i[1]); + break; + case 54: + i[0] = readInt(); + i[1] = readInt(); + xor_54(i[0], i[1]); + break; + case 55: + i[0] = readInt(); + not_55(i[0]); + break; + case 56: + i[0] = readInt(); + i[1] = readInt(); + cmp_56(i[0], i[1]); + break; + case 57: + i[0] = readInt(); + i[1] = readInt(); + cmpS_57(i[0], i[1]); + break; + case 58: + i[0] = readInt(); + i[1] = readInt(); + cmp_u_58(i[0], i[1]); + break; + case 59: + i[0] = readInt(); + jmp_59(i[0]); + break; + case 60: + i[0] = readInt(); + jmp_60(i[0]); + break; + case 61: + i[0] = readInt(); + je_61(i[0]); + break; + case 62: + i[0] = readInt(); + je_62(i[0]); + break; + case 63: + i[0] = readInt(); + jne_63(i[0]); + break; + case 64: + i[0] = readInt(); + jne_64(i[0]); + break; + case 65: + i[0] = readInt(); + jg_65(i[0]); + break; + case 66: + i[0] = readInt(); + jg_66(i[0]); + break; + case 67: + i[0] = readInt(); + jge_67(i[0]); + break; + case 68: + i[0] = readInt(); + jge_68(i[0]); + break; + case 69: + i[0] = readInt(); + jl_69(i[0]); + break; + case 70: + i[0] = readInt(); + jl_70(i[0]); + break; + case 71: + i[0] = readInt(); + jle_71(i[0]); + break; + case 72: + i[0] = readInt(); + jle_72(i[0]); + break; + case 73: + i[0] = readInt(); + obj_num_73(i[0]); + break; + case 74: + i[0] = readInt(); + i[1] = readInt(); + obj_num1_74(i[0], i[1]); + break; + case 75: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_num2_75(i[0], i[1], i[2]); + break; + case 76: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_num3_76(i[0], i[1], i[2], i[3]); + break; + case 77: + i[0] = readInt(); + obj_str_77(i[0]); + break; + case 78: + i[0] = readInt(); + i[1] = readInt(); + obj_str1_78(i[0], i[1]); + break; + case 79: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_str2_79(i[0], i[1], i[2]); + break; + case 80: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_str3_80(i[0], i[1], i[2], i[3]); + break; + case 81: + i[0] = readInt(); + obj_usr_81(i[0]); + break; + case 82: + i[0] = readInt(); + i[1] = readInt(); + obj_usr1_82(i[0], i[1]); + break; + case 83: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_usr2_83(i[0], i[1], i[2]); + break; + case 84: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_usr3_84(i[0], i[1], i[2], i[3]); + break; + case 85: + i[0] = readInt(); + obj_get_85(i[0]); + break; + case 86: + i[0] = readInt(); + obj_getS_86(i[0]); + break; + case 87: + i[0] = readInt(); + obj_set_87(i[0]); + break; + case 88: + i[0] = readInt(); + obj_setS_88(i[0]); + break; + case 89: + clear_obj_89(); + break; + case 90: + i[0] = readInt(); + i[1] = readInt(); + dim_type_90(i[0], i[1]); + break; + case 91: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + dim_type1_91(i[0], i[1], i[2]); + break; + case 92: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + dim_type2_92(i[0], i[1], i[2], i[3]); + break; + case 93: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + i[4] = readInt(); + dim_type3_93(i[0], i[1], i[2], i[3], i[4]); + break; + case 94: + i[0] = readInt(); + i[1] = readInt(); + dim_num1_94(i[0], i[1]); + break; + case 95: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + dim_num2_95(i[0], i[1], i[2]); + break; + case 96: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + dim_num3_96(i[0], i[1], i[2], i[3]); + break; + case 97: + i[0] = readInt(); + i[1] = readInt(); + dim_str1_97(i[0], i[1]); + break; + case 98: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + dim_str2_98(i[0], i[1], i[2]); + break; + case 99: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + dim_str3_99(i[0], i[1], i[2], i[3]); + break; + case 100: + i[0] = readInt(); + delete_100(i[0]); + break; + case 101: + i[0] = readInt(); + deleteS_101(i[0]); + break; + case 102: + i[0] = readInt(); + push_102(i[0]); + break; + case 103: + i[0] = readInt(); + push_103(i[0]); + break; + case 104: + i[0] = readInt(); + pushS_104(i[0]); + break; + case 105: + i[0] = readInt(); + pushS_105(i[0]); + break; + case 106: + push_emptyS_106(); + break; + case 107: + i[0] = readInt(); + pop_107(i[0]); + break; + case 108: + i[0] = readInt(); + pop_108(i[0]); + break; + case 109: + i[0] = readInt(); + popS_109(i[0]); + break; + case 110: + i[0] = readInt(); + popS_110(i[0]); + break; + case 111: + i[0] = readInt(); + get_stack_size_111(i[0]); + break; + case 112: + i[0] = readInt(); + get_stack_sizeS_112(i[0]); + break; + case 113: + clear_stack_113(); + break; + case 114: + clear_stackS_114(); + break; + case 115: + i[0] = readInt(); + i[1] = readInt(); + while_115(i[0], i[1]); + break; + case 116: + i[0] = readInt(); + wend_116(i[0]); + break; + case 117: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + //cout << "step = " << vm_n[i[3]].value << endl; + //cout << "for counter = " << vm_n[i[1]].value << " to " << vm_n[i[2]].value << " step " << vm_n[i[3]].value << endl; + for_117(i[0], i[1], i[2], i[3]); + //cout << "for info: " << current_segment << " " << current_address << endl << endl; + //cout << "for counter = " << vm_n[i[1]].value << " to " << vm_n[i[2]].value << " step " << vm_n[i[3]].value << endl; + break; + case 118: + i[0] = readInt(); + next_118(i[0]); + //cout << endl << "next to: " << i[0] << endl; + break; + case 119: + //do not really needed, so + break; + case 120: + i[0] = readInt(); + loop_120(i[0]); + break; + case 121: + i[0] = readInt(); + i[1] = readInt(); + loop_while_121(i[0], i[1]); + break; + case 122: + i[0] = readInt(); + i[1] = readInt(); + loop_until_122(i[0], i[1]); + break; + case 123: + pop_loop_stack_123(); + break; + case 124: + i[0] = readInt(); + gosub_124(i[0]); + break; + case 125: + return_125(); + break; + case 126: + i[0] = readInt(); + i[1] = readInt(); + ptr_126(i[0], i[1]); + break; + case 127: + i[0] = readInt(); + i[1] = readInt(); + ptrS_127(i[0], i[1]); + break; + case 128: + i[0] = readInt(); + print_128(i[0]); + break; + case 129: + i[0] = readInt(); + printS_129(i[0]); + break; + case 130: + i[0] = readInt(); + //cout << "func " << i[0] << endl; + func_130(i[0]); + break; + case 131: + d[0] = readDouble(); + push_131(d[0]); + break; + case 132: + println_132(); + break; + case 133: + i[0] = readInt(); + i[1] = readInt(); + mov_133(i[0], i[1]); + break; + case 134: + i[0] = readInt(); + d[0] = readDouble(); + cmp_134(i[0], d[0]); + break; + case 135: + i[0] = readInt(); + i[1] = readInt(); + mov_arr_135(i[0], i[1]); + break; + case 136: + i[0] = readInt(); + i[1] = readInt(); + mov_arrS_136(i[0], i[1]); + break; + case 137: + i[0] = readInt(); + pop_ptr_137(i[0]); + break; + case 138: + i[0] = readInt(); + preset_138(i[0]); + break; + case 139: + i[0] = readInt(); + presetS_139(i[0]); + break; + case 140: + i[0] = readInt(); + i[1] = readInt(); + redim_140(i[0], i[1]); + break; + case 141: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + redim_141(i[0], i[1], i[2]); + break; + case 142: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + redim_142(i[0], i[1], i[2], i[3]); + break; + case 143: + i[0] = readInt(); + i[1] = readInt(); + redimS_143(i[0], i[1]); + break; + case 144: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + redimS_144(i[0], i[1], i[2]); + break; + case 145: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + redimS_145(i[0], i[1], i[2], i[3]); + break; + case 146: + i[0] = readInt(); + for_offset_arr1_146(i[0]); + break; + case 147: + i[0] = readInt(); + i[1] = readInt(); + for_offset_arr2_147(i[0], i[1]); + break; + case 148: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + for_offset_arr3_148(i[0], i[1], i[2]); + break; + case 149: + for_offset_0_149(); + break; + case 150: + i[0] = readInt(); + end_x_150(i[0]); + end_of_program = true; + break; + case 151: + //lval + break; + case 152: + //lval + break; + case 153: + //lval + break; + case 154: + //lval + break; + case 155: + //lval + break; + case 156: + i[0] = readInt(); + obj_usr_n_156(i[0]); + break; + case 157: + i[0] = readInt(); + i[1] = readInt(); + obj_usr_n1_157(i[0], i[1]); + break; + case 158: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_usr_n2_158(i[0], i[1], i[2]); + break; + case 159: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_usr_n3_159(i[0], i[1], i[2], i[3]); + break; + case 160: + i[0] = readInt(); + obj_usr_s_160(i[0]); + break; + case 161: + i[0] = readInt(); + i[1] = readInt(); + obj_usr_s1_161(i[0], i[1]); + break; + case 162: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_usr_s2_162(i[0], i[1], i[2]); + break; + case 163: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_usr_s3_163(i[0], i[1], i[2], i[3]); + break; + case 164: + i[0] = readInt(); + obj_usr_get_164(i[0]); + break; + case 165: + i[0] = readInt(); + obj_usr_get_165(i[0]); + break; + case 166: + i[0] = readInt(); + obj_usr_get_166(i[0]); + break; + case 167: + i[0] = readInt(); + i[1] = readInt(); + uref_ptr_167(i[0], i[1]); + break; + case 168: + i[0] = readInt(); + i[1] = readInt(); + mov_type_168(i[0], i[1]); + break; + case 169: + i[0] = readInt(); + push_t_169(i[0]); + break; + case 170: + i[0] = readInt(); + push_t_170(i[0]); + break; + case 171: + i[0] = readInt(); + pop_t_171(i[0]); + break; + case 172: + i[0] = readInt(); + pop_t_172(i[0]); + break; + case 173: + push_t_null_173(); + break; + case 174: + i[0] = readInt(); + delete_t_174(i[0]); + break; + case 175: + i[0] = readInt(); + i[1] = readInt(); + dim_type_175(i[0], i[1]); + break; + case 176: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + dim_type1_176(i[0], i[1], i[2]); + break; + case 177: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + dim_type2_177(i[0], i[1], i[2], i[3]); + break; + case 178: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + i[4] = readInt(); + dim_type3_178(i[0], i[1], i[2], i[3], i[4]); + break; + case 179: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + i[4] = readInt(); + i[5] = readInt(); + i[6] = readInt(); + dim_tfield_179(i[0], i[1], i[2], i[3], i[4], i[5], i[6]); + break; + case 180: + i[0] = readInt(); + obj_usr_init_180(i[0]); + break; + case 181: + i[0] = readInt(); + i[1] = readInt(); + obj_usr_init1_181(i[0], i[1]); + break; + case 182: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_usr_init2_182(i[0], i[1], i[2]); + break; + case 183: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_usr_init3_183(i[0], i[1], i[2], i[3]); + break; + case 184: + i[0] = readInt(); + obj_usr_init_184(i[0]); + break; + case 185: + i[0] = readInt(); + i[1] = readInt(); + obj_usr_init1_185(i[0], i[1]); + break; + case 186: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + obj_usr_init2_186(i[0], i[1], i[2]); + break; + case 187: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + obj_usr_init3_187(i[0], i[1], i[2], i[3]); + break; + case 188: + i[0] = readInt(); + i[1] = readInt(); + preset_t_188(i[0], i[1]); + break; + case 189: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + preset_t1_189(i[0], i[1], i[2]); + break; + case 190: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + preset_t2_190(i[0], i[1], i[2], i[3]); + break; + case 191: + i[0] = readInt(); + i[1] = readInt(); + i[2] = readInt(); + i[3] = readInt(); + i[4] = readInt(); + preset_t3_191(i[0], i[1], i[2], i[3], i[4]); + break; + default: + cout << "invalid cmd: " << rcbasic_cmd << endl; + rcbasic_exit_code = 1; + return 0; + } + } + return 1; +} + +void rcbasic_init() +{ + for(int i = 0; i < RC_MAX_FILES; i++) + rc_fstream[i] = NULL; + rc_media_init(); + arr_ref_id.clear(); +} + +void rcbasic_clean() +{ + rc_media_quit(); + byref_addr_table.empty(); + loop_stack.empty(); + n_stack.empty(); + s_stack.empty(); + gosub_return_addr.empty(); +} + +void rcbasic_test() +{ + SDL_Init(SDL_INIT_EVERYTHING); + + SDL_Window * win = SDL_CreateWindow("test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN); + SDL_Renderer * ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC); + SDL_Rect src; + src.x = 50; + src.y = 50; + src.w = 100; + src.h = 100; + SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); + SDL_RenderFillRect(ren, &src); + SDL_RenderPresent(ren); + SDL_Delay(5000); + SDL_DestroyRenderer(ren); + SDL_DestroyWindow(win); +} + +int main(int argc, char * argv[]) +{ + //rcbasic_test(); + //return 0; + + if(argc > 0) + rcbasic_runtime_path = argv[0]; + + //cout << "RCBASIC RUNTIME START" << endl; + #ifdef RC_WINDOWS + TCHAR buf[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, buf); + rc_dir_path = buf; + SetConsoleOutputCP(CP_UTF8); + SetConsoleCP(CP_UTF8); + #else + #ifdef RC_GETCWD + char buf[2048]; + getcwd(buf, 2048); + rc_dir_path = (string)buf; + #else + rc_dir_path = get_current_dir_name(); + #endif + #endif // RC_WINDOWS + + string rc_filename = "main.cbc"; + + if(argc > 1) + rc_filename = argv[1]; + else + #ifdef RC_WINDOWS + { + //rc_filename = argv[0]; + //rc_filename = rc_filename.substr(0, rc_filename.length()-3) + "cbc"; + } + #else + { + //rc_filename = argv[0]; + //rc_filename += ".cbc"; + } + #endif // RC_WINDOWS + + if(rc_filename.compare("--version")==0) + { + cout << "RCBASIC Runtime v4.0a1" << endl; + return 0; + } + + #ifdef RCBASIC_DEBUG + rc_filename = "debug.cbc"; + #endif // RCBASIC_DEBUG + + //DEBUG START + //rc_filename = "/home/n00b/Projects/RCBASIC3/rcbasic_build/tst.cbc"; + //DEBUG END + + if(argc >1) + { + rc_cmd_count = argc - 1; + rc_cmd_args = new string[rc_cmd_count]; + for(int i = 1; i < argc; i++) + rc_cmd_args[i-1] = argv[i]; + } + + rcbasic_init(); + rc_initSubprocessSystem(); + + if(rc_filename.length()>=4) + { + if(rc_filename.substr(rc_filename.length()-4, 4).compare(".cbc")!=0) + rc_filename += ".cbc"; + } + else + { + rc_filename += ".cbc"; + } + +#ifdef RC_ANDROID + rc_filename = "main.cbc"; +#endif + +#ifdef RC_IOS + if( rc_intern_dirChange("assets")!=0) + { + cout << "could not set path" << endl; + return 0; + } + rc_filename = "main.cbc"; +#endif + + //cout << "starting: " << rc_filename << endl; + + #ifdef RC_WEB + rc_filename = "main.cbc"; + #endif + + if(rcbasic_load(rc_filename)) + { + #ifdef RCBASIC_DEBUG + loadDebugData("rcbasic.dbgs", "rcbasic.dbgi"); + #endif // RCBASIC_DEBUG + + //cout << "n_count = " << n_count << endl; + //cout << "s_count = " << s_count << endl; + //cout << "n_stack_size = " << n_stack_size << endl; + //cout << "s_stack_size = " << s_stack_size << endl; + //cout << "loop_stack_size = " << loop_stack_size << endl; + //cout << "numID_count = " << numID_count << endl; + //cout << "strID_count = " << strID_count << endl; + //cout << "code_segment_size = " << code_segment_size << endl; + //cout << "data_segment_size = " << data_segment_size << endl; + //cout << "last code = " << (int)segment[CODE_SEGMENT][code_segment_size-1] << endl; + //cout << "last data = " << (int)segment[DATA_SEGMENT][data_segment_size-1] << endl << endl; + + rcbasic_run(); + } + else + cout << "++Could not load rcbasic program" << endl; + + rc_cleanSubprocessSystem(); + rcbasic_clean(); + + exit(rcbasic_exit_code); + //cout << "Hello world!" << endl; + return 0; +} diff --git a/rcbasic_runtime/rc_defines.h b/rcbasic_runtime/rc_defines.h new file mode 100644 index 0000000..44c7403 --- /dev/null +++ b/rcbasic_runtime/rc_defines.h @@ -0,0 +1,1417 @@ +#define FN_FPrint 0 +#define FPRINT_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Input$ 1 +#define INPUT$_PROMPT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_ArrayDim 2 +#define ARRAYDIM_ID num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_StringArrayDim 3 +#define STRINGARRAYDIM_ID$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_NumberArrayDim 4 +#define NUMBERARRAYDIM_ID num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ArraySize 5 +#define ARRAYSIZE_ID num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ARRAYSIZE_ARRAY_DIM num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_StringArraySize 6 +#define STRINGARRAYSIZE_ID$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define STRINGARRAYSIZE_ARRAY_DIM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumberArraySize 7 +#define NUMBERARRAYSIZE_ID num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define NUMBERARRAYSIZE_ARRAY_DIM num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_Abs 8 +#define ABS_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ACos 9 +#define ACOS_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_AndBit 10 +#define ANDBIT_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ANDBIT_B num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ASin 11 +#define ASIN_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ATan 12 +#define ATAN_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Bin$ 13 +#define BIN$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_CInt32 14 +#define CINT32_I num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_CInt64 15 +#define CINT64_I num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Cos 16 +#define COS_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Degrees 17 +#define DEGREES_R num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Exp 18 +#define EXP_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Frac 19 +#define FRAC_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Hex$ 20 +#define HEX$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_HexVal 21 +#define HEXVAL_N$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Int 22 +#define INT_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Log 23 +#define LOG_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Max 24 +#define MAX_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define MAX_B num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_Min 25 +#define MIN_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define MIN_B num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_OrBit 26 +#define ORBIT_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ORBIT_B num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_Radians 27 +#define RADIANS_D num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Randomize 28 +#define RANDOMIZE_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Rand 29 +#define RAND_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Round 30 +#define ROUND_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Sign 31 +#define SIGN_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Sin 32 +#define SIN_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Sqrt 33 +#define SQRT_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Tan 34 +#define TAN_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_XOrBit 35 +#define XORBIT_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define XORBIT_B num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_Asc 36 +#define ASC_C$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Chr$ 37 +#define CHR$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Insert$ 38 +#define INSERT$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define INSERT$_TGT$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define INSERT$_POS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_InStr 39 +#define INSTR_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define INSTR_SUBSTR$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_LCase$ 40 +#define LCASE$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Left$ 41 +#define LEFT$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define LEFT$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Length 42 +#define LENGTH_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Len 43 +#define LEN_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_LTrim$ 44 +#define LTRIM$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Mid$ 45 +#define MID$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define MID$_START num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define MID$_N num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ReplaceSubstr$ 46 +#define REPLACESUBSTR$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define REPLACESUBSTR$_RPC$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define REPLACESUBSTR$_POS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Replace$ 47 +#define REPLACE$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define REPLACE$_TGT$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define REPLACE$_RPC$ str_var[2].sid_value.value[ str_var[2].byref_offset ] +#define FN_Reverse$ 48 +#define REVERSE$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Right$ 49 +#define RIGHT$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define RIGHT$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_RTrim$ 50 +#define RTRIM$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_StringFill$ 51 +#define STRINGFILL$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define STRINGFILL$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Str$ 52 +#define STR$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Str_F$ 53 +#define STR_F$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Str_S$ 54 +#define STR_S$_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Tally 55 +#define TALLY_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define TALLY_SUBSTR$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_Trim$ 56 +#define TRIM$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_UCase$ 57 +#define UCASE$_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Val 58 +#define VAL_N$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Stack_N 59 +#define STACK_N_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Stack_S 60 +#define STACK_S_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Push_N 61 +#define PUSH_N_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Pop_N 62 +#define FN_Push_S 63 +#define PUSH_S_S$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Pop_S$ 64 +#define FN_Stack_Size_N 65 +#define FN_Stack_Size_S 66 +#define FN_FileOpen 67 +#define FILEOPEN_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FILEOPEN_FILENAME$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FILEOPEN_MODE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_FileClose 68 +#define FILECLOSE_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ReadByte 69 +#define READBYTE_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WriteByte 70 +#define WRITEBYTE_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WRITEBYTE_BYTE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ReadLine$ 71 +#define READLINE$_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Write 72 +#define WRITE_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WRITE_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_WriteLine 73 +#define WRITELINE_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WRITELINE_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_CopyFile 74 +#define COPYFILE_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define COPYFILE_DST$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_RemoveFile 75 +#define REMOVEFILE_FILENAME$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_FileExists 76 +#define FILEEXISTS_FILENAME$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_MoveFile 77 +#define MOVEFILE_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define MOVEFILE_DST$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_RenameFile 78 +#define RENAMEFILE_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define RENAMEFILE_DST$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_FileLength 79 +#define FILELENGTH_FILENAME$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Tell 80 +#define TELL_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Seek 81 +#define SEEK_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SEEK_POS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_EOF 82 +#define EOF_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_FreeFile 83 +#define FN_ChangeDir 84 +#define CHANGEDIR_P$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_DirExists 85 +#define DIREXISTS_P$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_DirFirst$ 86 +#define FN_Dir$ 87 +#define FN_DirNext$ 88 +#define FN_MakeDir 89 +#define MAKEDIR_P$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_RemoveDir 90 +#define REMOVEDIR_P$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Date$ 91 +#define FN_Easter$ 92 +#define EASTER$_YEAR num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Ticks 93 +#define FN_Time$ 94 +#define FN_Timer 95 +#define FN_Wait 96 +#define WAIT_M_SEC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowOpen 97 +#define WINDOWOPEN_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WINDOWOPEN_TITLE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define WINDOWOPEN_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define WINDOWOPEN_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define WINDOWOPEN_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define WINDOWOPEN_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define WINDOWOPEN_FLAG num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define WINDOWOPEN_VSYNC num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define FN_WindowClose 98 +#define WINDOWCLOSE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_RaiseWindow 99 +#define RAISEWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Window 100 +#define WINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Update 101 +#define FN_Cls 102 +#define FN_SetClearColor 103 +#define SETCLEARCOLOR_C num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ShowWindow 104 +#define SHOWWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_HideWindow 105 +#define HIDEWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetWindowTitle 106 +#define SETWINDOWTITLE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWTITLE_TITLE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_WindowTitle$ 107 +#define WINDOWTITLE$_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetWindowPosition 108 +#define SETWINDOWPOSITION_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWPOSITION_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETWINDOWPOSITION_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_GetWindowPosition 109 +#define GETWINDOWPOSITION_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETWINDOWPOSITION_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETWINDOWPOSITION_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetWindowSize 110 +#define SETWINDOWSIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETWINDOWSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_GetWindowSize 111 +#define GETWINDOWSIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETWINDOWSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETWINDOWSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetWindowMinSize 112 +#define SETWINDOWMINSIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWMINSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETWINDOWMINSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_GetWindowMinSize 113 +#define GETWINDOWMINSIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETWINDOWMINSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETWINDOWMINSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetWindowMaxSize 114 +#define SETWINDOWMAXSIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWMAXSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETWINDOWMAXSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_GetWindowMaxSize 115 +#define GETWINDOWMAXSIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETWINDOWMAXSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETWINDOWMAXSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_WindowIsFullscreen 116 +#define WINDOWISFULLSCREEN_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowIsVisible 117 +#define WINDOWISVISIBLE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowIsBordered 118 +#define WINDOWISBORDERED_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowIsResizable 119 +#define WINDOWISRESIZABLE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowIsMinimized 120 +#define WINDOWISMINIMIZED_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowIsMaximized 121 +#define WINDOWISMAXIMIZED_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowHasInputFocus 122 +#define WINDOWHASINPUTFOCUS_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowHasMouseFocus 123 +#define WINDOWHASMOUSEFOCUS_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetWindowFullscreen 124 +#define SETWINDOWFULLSCREEN_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWFULLSCREEN_FLAG num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_MaximizeWindow 125 +#define MAXIMIZEWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_MinimizeWindow 126 +#define MINIMIZEWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetWindowBorder 127 +#define SETWINDOWBORDER_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWBORDER_FLAG num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_WindowClip 128 +#define WINDOWCLIP_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WINDOWCLIP_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define WINDOWCLIP_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define WINDOWCLIP_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define WINDOWCLIP_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_WindowExists 129 +#define WINDOWEXISTS_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumWindows 130 +#define FN_WindowEvent_Close 131 +#define WINDOWEVENT_CLOSE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowEvent_Maximize 132 +#define WINDOWEVENT_MAXIMIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WindowEvent_Minimize 133 +#define WINDOWEVENT_MINIMIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ActiveWindow 134 +#define FN_FPS 135 +#define FN_SetWindowIcon 136 +#define SETWINDOWICON_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWICON_SLOT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CanvasOpen 137 +#define CANVASOPEN_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CANVASOPEN_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CANVASOPEN_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define CANVASOPEN_VIEWPORT_X num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define CANVASOPEN_VIEWPORT_Y num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define CANVASOPEN_VIEWPORT_W num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define CANVASOPEN_VIEWPORT_H num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define CANVASOPEN_MODE num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define FN_CanvasClose 138 +#define CANVASCLOSE_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetCanvasVisible 139 +#define SETCANVASVISIBLE_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASVISIBLE_FLAG num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CanvasIsVisible 140 +#define CANVASISVISIBLE_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetCanvasViewport 141 +#define SETCANVASVIEWPORT_CNUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASVIEWPORT_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETCANVASVIEWPORT_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SETCANVASVIEWPORT_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define SETCANVASVIEWPORT_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_GetCanvasViewport 142 +#define GETCANVASVIEWPORT_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETCANVASVIEWPORT_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETCANVASVIEWPORT_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETCANVASVIEWPORT_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETCANVASVIEWPORT_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_Canvas 143 +#define CANVAS_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetCanvasOffset 144 +#define SETCANVASOFFSET_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASOFFSET_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETCANVASOFFSET_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_GetCanvasOffset 145 +#define GETCANVASOFFSET_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETCANVASOFFSET_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETCANVASOFFSET_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_GetCanvasSize 146 +#define GETCANVASSIZE_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETCANVASSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETCANVASSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_ClearCanvas 147 +#define FN_SetCanvasAlpha 148 +#define SETCANVASALPHA_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASALPHA_A num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CanvasAlpha 149 +#define CANVASALPHA_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetCanvasBlendMode 150 +#define SETCANVASBLENDMODE_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASBLENDMODE_BLEND_MODE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CanvasBlendMode 151 +#define CANVASBLENDMODE_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetCanvasColorMod 152 +#define SETCANVASCOLORMOD_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASCOLORMOD_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CanvasColorMod 153 +#define CANVASCOLORMOD_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_CopyCanvas 154 +#define COPYCANVAS_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define COPYCANVAS_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define COPYCANVAS_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define COPYCANVAS_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define COPYCANVAS_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define COPYCANVAS_DST num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define COPYCANVAS_DX num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define COPYCANVAS_DY num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define FN_CloneCanvas 155 +#define CLONECANVAS_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CLONECANVAS_DST num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SetCanvasZ 156 +#define SETCANVASZ_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCANVASZ_Z num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CanvasZ 157 +#define CANVASZ_C_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_CanvasClip 158 +#define CANVASCLIP_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CANVASCLIP_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CANVASCLIP_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define CANVASCLIP_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define CANVASCLIP_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define CANVASCLIP_FLAG num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define FN_ActiveCanvas 159 +#define FN_Box 160 +#define BOX_X1 num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define BOX_Y1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define BOX_X2 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define BOX_Y2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_BoxFill 161 +#define BOXFILL_X1 num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define BOXFILL_Y1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define BOXFILL_X2 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define BOXFILL_Y2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_Circle 162 +#define CIRCLE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CIRCLE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CIRCLE_RADIUS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_CircleFill 163 +#define CIRCLEFILL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CIRCLEFILL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CIRCLEFILL_RADIUS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_Ellipse 164 +#define ELLIPSE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ELLIPSE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ELLIPSE_RX num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define ELLIPSE_RY num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_EllipseFill 165 +#define ELLIPSEFILL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ELLIPSEFILL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ELLIPSEFILL_RX num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define ELLIPSEFILL_RY num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_FloodFill 166 +#define FLOODFILL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FLOODFILL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_GetPixel 167 +#define GETPIXEL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETPIXEL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SetColor 168 +#define SETCOLOR_C num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Line 169 +#define LINE_X1 num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define LINE_Y1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define LINE_X2 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define LINE_Y2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_Poly 170 +#define POLY_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define POLY_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define POLY_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_PolyFill 171 +#define POLYFILL_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define POLYFILL_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define POLYFILL_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_Rect 172 +#define RECT_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define RECT_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define RECT_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define RECT_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_RectFill 173 +#define RECTFILL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define RECTFILL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define RECTFILL_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define RECTFILL_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_RoundRect 174 +#define ROUNDRECT_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ROUNDRECT_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ROUNDRECT_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define ROUNDRECT_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define ROUNDRECT_R num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_RoundRectFill 175 +#define ROUNDRECTFILL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ROUNDRECTFILL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ROUNDRECTFILL_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define ROUNDRECTFILL_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define ROUNDRECTFILL_R num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_RGB 176 +#define RGB_R num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define RGB_G num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define RGB_B num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_RGBA 177 +#define RGBA_R num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define RGBA_G num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define RGBA_B num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define RGBA_A num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_PSet 178 +#define PSET_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define PSET_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_LoadImage 179 +#define LOADIMAGE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define LOADIMAGE_IMG$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_LoadImage_Ex 180 +#define LOADIMAGE_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define LOADIMAGE_EX_IMG$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define LOADIMAGE_EX_COLKEY num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ImageFromBuffer 181 +#define IMAGEFROMBUFFER_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define IMAGEFROMBUFFER_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define IMAGEFROMBUFFER_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define IMAGEFROMBUFFER_BUFFER num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_ImageFromBuffer_Ex 182 +#define IMAGEFROMBUFFER_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define IMAGEFROMBUFFER_EX_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define IMAGEFROMBUFFER_EX_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define IMAGEFROMBUFFER_EX_BUFFER num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define IMAGEFROMBUFFER_EX_COLKEY num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_BufferFromImage 183 +#define BUFFERFROMIMAGE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define BUFFERFROMIMAGE_BUFFER num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ImageExists 184 +#define IMAGEEXISTS_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ColorKey 185 +#define COLORKEY_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define COLORKEY_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_CopyImage 186 +#define COPYIMAGE_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define COPYIMAGE_DST num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_DeleteImage 187 +#define DELETEIMAGE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetImageAlpha 188 +#define SETIMAGEALPHA_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETIMAGEALPHA_A num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ImageAlpha 189 +#define IMAGEALPHA_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_GetImageSize 190 +#define GETIMAGESIZE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETIMAGESIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETIMAGESIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetImageBlendMode 191 +#define SETIMAGEBLENDMODE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETIMAGEBLENDMODE_BLEND_MODE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ImageBlendMode 192 +#define IMAGEBLENDMODE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetImageColorMod 193 +#define SETIMAGECOLORMOD_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETIMAGECOLORMOD_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ImageColorMod 194 +#define IMAGECOLORMOD_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_DrawImage 195 +#define DRAWIMAGE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_DrawImage_Blit 196 +#define DRAWIMAGE_BLIT_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_BLIT_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_BLIT_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_BLIT_SRC_X num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_BLIT_SRC_Y num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_BLIT_SRC_W num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_BLIT_SRC_H num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define FN_DrawImage_Blit_Ex 197 +#define DRAWIMAGE_BLIT_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_BLIT_EX_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_BLIT_EX_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_BLIT_EX_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_BLIT_EX_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_BLIT_EX_SRC_X num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_BLIT_EX_SRC_Y num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define DRAWIMAGE_BLIT_EX_SRC_W num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define DRAWIMAGE_BLIT_EX_SRC_H num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define FN_DrawImage_Rotate 198 +#define DRAWIMAGE_ROTATE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_ROTATE_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_ROTATE_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_ROTATE_ANGLE num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_DrawImage_Rotate_Ex 199 +#define DRAWIMAGE_ROTATE_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_SRC_X num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_SRC_Y num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_SRC_W num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_SRC_H num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define DRAWIMAGE_ROTATE_EX_ANGLE num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define FN_DrawImage_Zoom 200 +#define DRAWIMAGE_ZOOM_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_ZOOM_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_ZOOM_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_ZOOM_ZX num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_ZOOM_ZY num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_DrawImage_Zoom_Ex 201 +#define DRAWIMAGE_ZOOM_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_SRC_X num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_SRC_Y num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_SRC_W num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_SRC_H num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_ZX num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define DRAWIMAGE_ZOOM_EX_ZY num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define FN_DrawImage_Rotozoom 202 +#define DRAWIMAGE_ROTOZOOM_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_ANGLE num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_ZX num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_ZY num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define FN_DrawImage_Rotozoom_Ex 203 +#define DRAWIMAGE_ROTOZOOM_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_SRC_X num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_SRC_Y num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_SRC_W num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_SRC_H num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_ANGLE num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_ZX num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define DRAWIMAGE_ROTOZOOM_EX_ZY num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define FN_DrawImage_Flip 204 +#define DRAWIMAGE_FLIP_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_FLIP_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_FLIP_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_FLIP_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_FLIP_V num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_DrawImage_Flip_Ex 205 +#define DRAWIMAGE_FLIP_EX_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_FLIP_EX_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_FLIP_EX_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_FLIP_EX_SRC_X num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_FLIP_EX_SRC_Y num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_FLIP_EX_SRC_W num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_FLIP_EX_SRC_H num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define DRAWIMAGE_FLIP_EX_H num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define DRAWIMAGE_FLIP_EX_V num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define FN_InKey 206 +#define FN_Key 207 +#define KEY_KEY_CODE num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WaitKey 208 +#define FN_HideMouse 209 +#define FN_ShowMouse 210 +#define FN_MouseIsVisible 211 +#define FN_GetMouse 212 +#define GETMOUSE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETMOUSE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETMOUSE_MB1 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETMOUSE_MB2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETMOUSE_MB3 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_MouseX 213 +#define FN_MouseY 214 +#define FN_MouseButton 215 +#define MOUSEBUTTON_MB num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_GetMouseWheel 216 +#define GETMOUSEWHEEL_X_AXIS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETMOUSEWHEEL_Y_AXIS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_MouseWheelX 217 +#define FN_MouseWheelY 218 +#define FN_SoundFromBuffer 219 +#define SOUNDFROMBUFFER_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SOUNDFROMBUFFER_BUFFER num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SOUNDFROMBUFFER_BUFFER_SIZE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SOUNDFROMBUFFER_VOL num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_LoadSound 220 +#define LOADSOUND_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define LOADSOUND_SND_FILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_LoadMusic 221 +#define LOADMUSIC_MUSIC_FILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_PlaySound 222 +#define PLAYSOUND_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define PLAYSOUND_CHANNEL num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define PLAYSOUND_LOOPS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_PlaySoundTimed 223 +#define PLAYSOUNDTIMED_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define PLAYSOUNDTIMED_CHANNEL num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define PLAYSOUNDTIMED_LOOPS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define PLAYSOUNDTIMED_MS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_PlayMusic 224 +#define PLAYMUSIC_MLOOPS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_PauseSound 225 +#define PAUSESOUND_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ResumeSound 226 +#define RESUMESOUND_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_PauseMusic 227 +#define FN_ResumeMusic 228 +#define FN_DeleteSound 229 +#define DELETESOUND_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_DeleteMusic 230 +#define FN_FadeMusicIn 231 +#define FADEMUSICIN_FADE_TIME num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FADEMUSICIN_LOOPS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_FadeMusicOut 232 +#define FADEMUSICOUT_FADE_TIME num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_MusicExists 233 +#define FN_SetMusicVolume 234 +#define SETMUSICVOLUME_VOL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_MusicVolume 235 +#define FN_SetMusicPosition 236 +#define SETMUSICPOSITION_POS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_MusicPosition 237 +#define FN_RewindMusic 238 +#define FN_SetSoundChannels 239 +#define SETSOUNDCHANNELS_MAX_CHANNELS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumSoundChannels 240 +#define FN_SoundIsEnabled 241 +#define FN_SoundExists 242 +#define SOUNDEXISTS_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetChannelVolume 243 +#define SETCHANNELVOLUME_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCHANNELVOLUME_VOL num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ChannelVolume 244 +#define CHANNELVOLUME_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetSoundVolume 245 +#define SETSOUNDVOLUME_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETSOUNDVOLUME_VOL num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SoundVolume 246 +#define SOUNDVOLUME_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_StopMusic 247 +#define FN_StopSound 248 +#define STOPSOUND_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetChannelPanning 249 +#define SETCHANNELPANNING_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCHANNELPANNING_LEFT_VALUE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETCHANNELPANNING_RIGHT_VALUE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetChannelDistance 250 +#define SETCHANNELDISTANCE_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCHANNELDISTANCE_DIST_VALUE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ChannelIsPlaying 251 +#define CHANNELISPLAYING_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ChannelIsPaused 252 +#define CHANNELISPAUSED_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumJoysticks 253 +#define FN_NumJoyAxes 254 +#define NUMJOYAXES_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumJoyButtons 255 +#define NUMJOYBUTTONS_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumJoyHats 256 +#define NUMJOYHATS_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumJoyTrackBalls 257 +#define NUMJOYTRACKBALLS_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_JoyAxis 258 +#define JOYAXIS_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define JOYAXIS_JOY_AXIS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_JoyButton 259 +#define JOYBUTTON_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define JOYBUTTON_JOY_BUTTON num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_JoyHat 260 +#define JOYHAT_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define JOYHAT_JOY_HAT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_GetJoyTrackBall 261 +#define GETJOYTRACKBALL_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETJOYTRACKBALL_BALL num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETJOYTRACKBALL_DX num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETJOYTRACKBALL_DY num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_JoyName$ 262 +#define JOYNAME$_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_JoystickIsConnected 263 +#define JOYSTICKISCONNECTED_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_GetCursor 264 +#define GETCURSOR_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETCURSOR_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_PrintS 265 +#define PRINTS_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_InputS$ 266 +#define INPUTS$_PROMPT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_ZoneInputS$ 267 +#define ZONEINPUTS$_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ZONEINPUTS$_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ZONEINPUTS$_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define ZONEINPUTS$_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_Locate 268 +#define LOCATE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define LOCATE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ReadInput_Start 269 +#define FN_ReadInput_Stop 270 +#define FN_ReadInput_Text$ 271 +#define FN_ReadInput_SetText 272 +#define READINPUT_SETTEXT_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_ReadInput_ToggleBackspace 273 +#define READINPUT_TOGGLEBACKSPACE_FLAG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_LoadFont 274 +#define LOADFONT_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define LOADFONT_FNT_FILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define LOADFONT_SIZE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_DeleteFont 275 +#define DELETEFONT_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_FontIsLoaded 276 +#define FONTISLOADED_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_Font 277 +#define FONT_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetFontStyle 278 +#define SETFONTSTYLE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETFONTSTYLE_STYLE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_DrawText 279 +#define DRAWTEXT_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define DRAWTEXT_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWTEXT_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_DrawText_Shaded 280 +#define DRAWTEXT_SHADED_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define DRAWTEXT_SHADED_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWTEXT_SHADED_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWTEXT_SHADED_FG_COLOR num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWTEXT_SHADED_BG_COLOR num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_DrawText_Blended 281 +#define DRAWTEXT_BLENDED_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define DRAWTEXT_BLENDED_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWTEXT_BLENDED_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_RenderText 282 +#define RENDERTEXT_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define RENDERTEXT_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_GetTextSize 283 +#define GETTEXTSIZE_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETTEXTSIZE_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define GETTEXTSIZE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETTEXTSIZE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_TouchPressure 284 +#define FN_GetTouch 285 +#define GETTOUCH_STATUS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETTOUCH_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETTOUCH_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETTOUCH_DX num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETTOUCH_DY num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_GetMultiTouch 286 +#define GETMULTITOUCH_STATUS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETMULTITOUCH_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETMULTITOUCH_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETMULTITOUCH_FINGERS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETMULTITOUCH_DIST num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define GETMULTITOUCH_THETA num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define FN_GetTouchFinger 287 +#define GETTOUCHFINGER_FINGER num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETTOUCHFINGER_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETTOUCHFINGER_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETTOUCHFINGER_PRESSURE num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_NumFingers 288 +#define FN_CheckSockets 289 +#define CHECKSOCKETS_TIMEOUT_MS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_TCP_SocketReady 290 +#define TCP_SOCKETREADY_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_UDP_SocketReady 291 +#define UDP_SOCKETREADY_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_TCP_SocketOpen 292 +#define TCP_SOCKETOPEN_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define TCP_SOCKETOPEN_HOST$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define TCP_SOCKETOPEN_PORT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_TCP_SocketClose 293 +#define TCP_SOCKETCLOSE_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_TCP_RemoteHost 294 +#define TCP_REMOTEHOST_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_TCP_RemotePort 295 +#define TCP_REMOTEPORT_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_TCP_GetData 296 +#define TCP_GETDATA_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define TCP_GETDATA_SDATA$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define TCP_GETDATA_NUMBYTES num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_TCP_SendData 297 +#define TCP_SENDDATA_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define TCP_SENDDATA_SDATA$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_TCP_AcceptSocket 298 +#define TCP_ACCEPTSOCKET_SERVER num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define TCP_ACCEPTSOCKET_CLIENT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_UDP_SocketOpen 299 +#define UDP_SOCKETOPEN_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define UDP_SOCKETOPEN_PORT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_UDP_SocketClose 300 +#define UDP_SOCKETCLOSE_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_UDP_GetData 301 +#define UDP_GETDATA_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define UDP_GETDATA_SDATA$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define UDP_GETDATA_HOST$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define UDP_GETDATA_PORT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_UDP_Length 302 +#define FN_UDP_MaxLength 303 +#define FN_UDP_RemoteHost$ 304 +#define UDP_REMOTEHOST$_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_UDP_RemotePort 305 +#define UDP_REMOTEPORT_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_UDP_SendData 306 +#define UDP_SENDDATA_SOCKET num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define UDP_SENDDATA_SDATA$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define UDP_SENDDATA_HOST$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define UDP_SENDDATA_PORT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_LoadVideo 307 +#define LOADVIDEO_VID$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_PlayVideo 308 +#define PLAYVIDEO_VLOOPS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_PauseVideo 309 +#define FN_StopVideo 310 +#define FN_SetVideoPosition 311 +#define SETVIDEOPOSITION_POS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ResumeVideo 312 +#define FN_VideoPosition 313 +#define FN_DeleteVideo 314 +#define FN_VideoIsPlaying 315 +#define FN_VideoEnd 316 +#define FN_GetVideoStats 317 +#define GETVIDEOSTATS_VFILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define GETVIDEOSTATS_VLEN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETVIDEOSTATS_VFPS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETVIDEOSTATS_FRAME_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETVIDEOSTATS_FRAME_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_SetVideoDrawRect 318 +#define SETVIDEODRAWRECT_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETVIDEODRAWRECT_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETVIDEODRAWRECT_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SETVIDEODRAWRECT_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_GetVideoDrawRect 319 +#define GETVIDEODRAWRECT_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETVIDEODRAWRECT_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETVIDEODRAWRECT_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETVIDEODRAWRECT_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_GetVideoSize 320 +#define GETVIDEOSIZE_W num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETVIDEOSIZE_H num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_VideoExists 321 +#define FN_SetVideoAlpha 322 +#define SETVIDEOALPHA_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_System 323 +#define SYSTEM_CMD$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_OS$ 324 +#define FN_Command$ 325 +#define COMMAND$_ARG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumCommands 326 +#define FN_Env$ 327 +#define ENV$_V$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_SetEnv 328 +#define SETENV_VAR$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define SETENV_VALUE$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define SETENV_OVERWRITE num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_PrefPath$ 329 +#define PREFPATH$_ORG_NAME$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define PREFPATH$_APP_NAME$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_Android_GetExternalStoragePath$ 330 +#define FN_Android_GetExternalStorageState 331 +#define FN_Android_GetInternalStoragePath$ 332 +#define FN_Android_JNI_Message$ 333 +#define ANDROID_JNI_MESSAGE$_ARG$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_Runtime_Utility_Message$ 334 +#define RUNTIME_UTILITY_MESSAGE$_ARG$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_ClipboardText$ 335 +#define FN_SetClipboardText 336 +#define SETCLIPBOARDTEXT_TXT$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_HasClipboardText 337 +#define FN_GetDesktopDisplayMode 338 +#define GETDESKTOPDISPLAYMODE_INDEX num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETDESKTOPDISPLAYMODE_W num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETDESKTOPDISPLAYMODE_H num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETDESKTOPDISPLAYMODE_FREQ num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_DrawImage_Transform 339 +#define DRAWIMAGE_TRANSFORM_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWIMAGE_TRANSFORM_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWIMAGE_TRANSFORM_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWIMAGE_TRANSFORM_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWIMAGE_TRANSFORM_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DRAWIMAGE_TRANSFORM_SRC_X num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define DRAWIMAGE_TRANSFORM_SRC_Y num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define DRAWIMAGE_TRANSFORM_SRC_W num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define DRAWIMAGE_TRANSFORM_SRC_H num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define DRAWIMAGE_TRANSFORM_ANGLE num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define DRAWIMAGE_TRANSFORM_CENTER_X num_var[10].nid_value.value[ num_var[10].byref_offset ] +#define DRAWIMAGE_TRANSFORM_CENTER_Y num_var[11].nid_value.value[ num_var[11].byref_offset ] +#define DRAWIMAGE_TRANSFORM_FLIP_H num_var[12].nid_value.value[ num_var[12].byref_offset ] +#define DRAWIMAGE_TRANSFORM_FLIP_V num_var[13].nid_value.value[ num_var[13].byref_offset ] +#define FN_GetPowerInfo 340 +#define GETPOWERINFO_STATUS num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETPOWERINFO_SECS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETPOWERINFO_PCT num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SystemRam 341 +#define FN_SetRenderScaleQuality 342 +#define SETRENDERSCALEQUALITY_N num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_EvalJS$ 343 +#define EVALJS$_JS_CODE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_GetRenderScaleQuality 344 +#define FN_GetGlobalMouse 345 +#define GETGLOBALMOUSE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETGLOBALMOUSE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETGLOBALMOUSE_MB1 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETGLOBALMOUSE_MB2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETGLOBALMOUSE_MB3 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_GlobalMouseX 346 +#define FN_GlobalMouseY 347 +#define FN_GetAccel 348 +#define GETACCEL_ACCEL_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETACCEL_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETACCEL_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETACCEL_Z num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_AccelName$ 349 +#define ACCELNAME$_ACCEL_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumAccels 350 +#define FN_GetGyro 351 +#define GETGYRO_GYRO_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETGYRO_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETGYRO_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETGYRO_Z num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_GyroName$ 352 +#define GYRONAME$_GYRO_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumGyros 353 +#define FN_JoyRumblePlay 354 +#define JOYRUMBLEPLAY_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define JOYRUMBLEPLAY_STRENGTH num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define JOYRUMBLEPLAY_DURATION num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_JoyRumbleStop 355 +#define JOYRUMBLESTOP_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_JoystickIsHaptic 356 +#define JOYSTICKISHAPTIC_JOY_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_WriteByteBuffer 357 +#define WRITEBYTEBUFFER_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WRITEBYTEBUFFER_BUF num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define WRITEBYTEBUFFER_BUF_SIZE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_ReadByteBuffer 358 +#define READBYTEBUFFER_STREAM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define READBYTEBUFFER_BUF num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define READBYTEBUFFER_BUF_SIZE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_WindowEvent_Resize 359 +#define WINDOWEVENT_RESIZE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetWindowAutoClose 360 +#define SETWINDOWAUTOCLOSE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWAUTOCLOSE_EXIT_ON_CLOSE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SetWindowResizable 361 +#define SETWINDOWRESIZABLE_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWRESIZABLE_FLAG num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SystemReturnStdOut$ 362 +#define SYSTEMRETURNSTDOUT$_CMD$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_WindowMode 363 +#define WINDOWMODE_VISIBLE num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WINDOWMODE_FULLSCREEN num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define WINDOWMODE_RESIZABLE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define WINDOWMODE_BORDERLESS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define WINDOWMODE_HIGHDPI num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_WindowFlags 364 +#define WINDOWFLAGS_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_RestoreWindow 365 +#define RESTOREWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_UpdateAllWindows 366 +#define FN_QueryAudioSpec 367 +#define QUERYAUDIOSPEC_FREQ num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define QUERYAUDIOSPEC_FORMAT num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define QUERYAUDIOSPEC_CHANNELS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_MusicIsPlaying 368 +#define FN_DrawGeometry 369 +#define DRAWGEOMETRY_SLOT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DRAWGEOMETRY_NUM_VERTICES num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DRAWGEOMETRY_VERTICES num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DRAWGEOMETRY_NUM_INDICES num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DRAWGEOMETRY_INDICES num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_Size 370 +#define SIZE_S$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_BufferFromString 371 +#define BUFFERFROMSTRING_S$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define BUFFERFROMSTRING_BUFFER num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_StringFromBuffer$ 372 +#define STRINGFROMBUFFER$_BUFFER num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define STRINGFROMBUFFER$_BUFFER_SIZE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_GrabInput 373 +#define GRABINPUT_FLAG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_GrabbedWindow 374 +#define FN_WarpMouse 375 +#define WARPMOUSE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WARPMOUSE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_WarpMouseGlobal 376 +#define WARPMOUSEGLOBAL_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define WARPMOUSEGLOBAL_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SetMouseZone 377 +#define SETMOUSEZONE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETMOUSEZONE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETMOUSEZONE_W num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SETMOUSEZONE_H num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_ClearMouseZone 378 +#define FN_SetWindowAlwaysOnTop 379 +#define SETWINDOWALWAYSONTOP_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWALWAYSONTOP_FLAG num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SetMouseRelative 380 +#define SETMOUSERELATIVE_FLAG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetWindowVSync 381 +#define SETWINDOWVSYNC_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETWINDOWVSYNC_FLAG num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_OpenURL 382 +#define OPENURL_URL$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_APIVersion$ 383 +#define FN_FlashWindow 384 +#define FLASHWINDOW_WIN num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_MessageBox 385 +#define MESSAGEBOX_TITLE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define MESSAGEBOX_MSG$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_NumberArrayCopy 386 +#define NUMBERARRAYCOPY_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define NUMBERARRAYCOPY_DST num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_StringArrayCopy 387 +#define STRINGARRAYCOPY_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define STRINGARRAYCOPY_DST$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_ArrayCopy 388 +#define ARRAYCOPY_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ARRAYCOPY_DST num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_NumberArrayFill 389 +#define NUMBERARRAYFILL_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define NUMBERARRAYFILL_FDATA num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_StringArrayFill 390 +#define STRINGARRAYFILL_SRC$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define STRINGARRAYFILL_FDATA$ str_var[1].sid_value.value[ str_var[1].byref_offset ] +#define FN_ArrayFill 391 +#define ARRAYFILL_SRC num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ARRAYFILL_FDATA num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_Runtime$ 392 +#define FN_DimMatrix 393 +#define DIMMATRIX_M num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DIMMATRIX_M_ROWS num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DIMMATRIX_M_COLS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DIMMATRIX_PRESERVE_FLAG num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_AddMatrix 394 +#define ADDMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ADDMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ADDMATRIX_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_AugmentMatrix 395 +#define AUGMENTMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define AUGMENTMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define AUGMENTMATRIX_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_CopyMatrix 396 +#define COPYMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define COPYMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_InsertMatrixColumns 397 +#define INSERTMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define INSERTMATRIXCOLUMNS_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define INSERTMATRIXCOLUMNS_NUM_COLS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_InsertMatrixRows 398 +#define INSERTMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define INSERTMATRIXROWS_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define INSERTMATRIXROWS_NUM_ROWS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_MultiplyMatrix 399 +#define MULTIPLYMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define MULTIPLYMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define MULTIPLYMATRIX_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_CubeMatrix 400 +#define CUBEMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CUBEMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_DeleteMatrixColumns 401 +#define DELETEMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DELETEMATRIXCOLUMNS_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DELETEMATRIXCOLUMNS_NUM_COLS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_DeleteMatrixRows 402 +#define DELETEMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DELETEMATRIXROWS_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DELETEMATRIXROWS_NUM_ROWS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_ClearMatrix 403 +#define CLEARMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ClearMatrixColumns 404 +#define CLEARMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CLEARMATRIXCOLUMNS_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CLEARMATRIXCOLUMNS_NUM_COLS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_ClearMatrixRows 405 +#define CLEARMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CLEARMATRIXROWS_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CLEARMATRIXROWS_NUM_ROWS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_FillMatrix 406 +#define FILLMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FILLMATRIX_V num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_FillMatrixColumns 407 +#define FILLMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FILLMATRIXCOLUMNS_C num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FILLMATRIXCOLUMNS_NUM_COLS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FILLMATRIXCOLUMNS_V num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_FillMatrixRows 408 +#define FILLMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FILLMATRIXROWS_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FILLMATRIXROWS_NUM_ROWS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FILLMATRIXROWS_V num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_CopyMatrixColumns 409 +#define COPYMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define COPYMATRIXCOLUMNS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define COPYMATRIXCOLUMNS_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define COPYMATRIXCOLUMNS_NUM_COLS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_CopyMatrixRows 410 +#define COPYMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define COPYMATRIXROWS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define COPYMATRIXROWS_R num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define COPYMATRIXROWS_NUM_ROWS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_IdentityMatrix 411 +#define IDENTITYMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define IDENTITYMATRIX_N num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SolveMatrix 412 +#define SOLVEMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SOLVEMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SOLVEMATRIX_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_IsEqualMatrix 413 +#define ISEQUALMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ISEQUALMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define ISEQUALMATRIX_TOLERANCE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_Determinant 414 +#define DETERMINANT_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_AdjointMatrix 415 +#define ADJOINTMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ADJOINTMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_InvertMatrix 416 +#define INVERTMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define INVERTMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_MatrixFromBuffer 417 +#define MATRIXFROMBUFFER_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define MATRIXFROMBUFFER_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define MATRIXFROMBUFFER_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define MATRIXFROMBUFFER_BUFFER num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_GetMatrix 418 +#define GETMATRIX_BUFFER num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETMATRIX_MA num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_RandomizeMatrix 419 +#define RANDOMIZEMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define RANDOMIZEMATRIX_VMIN num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define RANDOMIZEMATRIX_VMAX num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_MatrixValue 420 +#define MATRIXVALUE_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define MATRIXVALUE_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define MATRIXVALUE_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetMatrixValue 421 +#define SETMATRIXVALUE_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETMATRIXVALUE_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETMATRIXVALUE_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SETMATRIXVALUE_V num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_ScalarMatrix 422 +#define SCALARMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SCALARMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SCALARMATRIX_S_VALUE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_ScalarMatrixColumns 423 +#define SCALARMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SCALARMATRIXCOLUMNS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SCALARMATRIXCOLUMNS_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SCALARMATRIXCOLUMNS_NUM_COLS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define SCALARMATRIXCOLUMNS_S_VALUE num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_ScalarMatrixRows 424 +#define SCALARMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SCALARMATRIXROWS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SCALARMATRIXROWS_R num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define SCALARMATRIXROWS_NUM_ROWS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define SCALARMATRIXROWS_S_VALUE num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_SquareMatrix 425 +#define SQUAREMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SQUAREMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SubMatrix 426 +#define SUBMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SUBMATRIX_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SUBMATRIX_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SubtractMatrix 427 +#define SUBTRACTMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SUBTRACTMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SUBTRACTMATRIX_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SwapMatrix 428 +#define SWAPMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SWAPMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_SwapMatrixColumn 429 +#define SWAPMATRIXCOLUMN_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SWAPMATRIXCOLUMN_C1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SWAPMATRIXCOLUMN_C2 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SwapMatrixRow 430 +#define SWAPMATRIXROW_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SWAPMATRIXROW_R1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SWAPMATRIXROW_R2 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_TransposeMatrix 431 +#define TRANSPOSEMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define TRANSPOSEMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_UnAugmentMatrix 432 +#define UNAUGMENTMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define UNAUGMENTMATRIX_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define UNAUGMENTMATRIX_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_ZeroMatrix 433 +#define ZEROMATRIX_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_GetMatrixSize 434 +#define GETMATRIXSIZE_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETMATRIXSIZE_R num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETMATRIXSIZE_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SetMatrixProcess 435 +#define SETMATRIXPROCESS_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessOpen 436 +#define PROCESSOPEN_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_SetProcessErrorMode 437 +#define SETPROCESSERRORMODE_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETPROCESSERRORMODE_ERROR_MODE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ProcessError 438 +#define PROCESSERROR_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessWait 439 +#define PROCESSWAIT_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessWaitAll 440 +#define FN_ProcessContinue 441 +#define PROCESSCONTINUE_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessStop 442 +#define PROCESSSTOP_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessClear 443 +#define PROCESSCLEAR_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessClose 444 +#define PROCESSCLOSE_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessErrorMode 445 +#define PROCESSERRORMODE_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessSleep 446 +#define PROCESSSLEEP_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define PROCESSSLEEP_MSEC num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_ProcessExists 447 +#define PROCESSEXISTS_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_ProcessStopAll 448 +#define FN_ProcessContinueAll 449 +#define FN_ProcessQueueSize 450 +#define PROCESSQUEUESIZE_P_NUM num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define FN_NumCPUs 451 +#define FN_GetProjectionGeometry 452 +#define GETPROJECTIONGEOMETRY_CAM_DIST num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETPROJECTIONGEOMETRY_MA num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETPROJECTIONGEOMETRY_F_VERTEX_COUNT num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETPROJECTIONGEOMETRY_COLUMNS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETPROJECTIONGEOMETRY_UV num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define GETPROJECTIONGEOMETRY_GRAPH_OFFSET_X num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define GETPROJECTIONGEOMETRY_GRAPH_OFFSET_Y num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define GETPROJECTIONGEOMETRY_V_COLOR num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define GETPROJECTIONGEOMETRY_VERTEX_COUNT num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define GETPROJECTIONGEOMETRY_VERTEX2D num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define GETPROJECTIONGEOMETRY_INDEX_COUNT num_var[10].nid_value.value[ num_var[10].byref_offset ] +#define GETPROJECTIONGEOMETRY_INDEX num_var[11].nid_value.value[ num_var[11].byref_offset ] +#define GETPROJECTIONGEOMETRY_CLIP_DIST num_var[12].nid_value.value[ num_var[12].byref_offset ] +#define GETPROJECTIONGEOMETRY_MIN_X num_var[13].nid_value.value[ num_var[13].byref_offset ] +#define GETPROJECTIONGEOMETRY_MIN_Y num_var[14].nid_value.value[ num_var[14].byref_offset ] +#define GETPROJECTIONGEOMETRY_MAX_X num_var[15].nid_value.value[ num_var[15].byref_offset ] +#define GETPROJECTIONGEOMETRY_MAX_Y num_var[16].nid_value.value[ num_var[16].byref_offset ] +#define FN_CalculateFaceZ 453 +#define CALCULATEFACEZ_CAM_DIST num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define CALCULATEFACEZ_GRAPH_OFFSET_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define CALCULATEFACEZ_GRAPH_OFFSET_Y num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define CALCULATEFACEZ_VIEW_W num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define CALCULATEFACEZ_VIEW_H num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define CALCULATEFACEZ_VIEW_DEPTH num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define CALCULATEFACEZ_MA num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define CALCULATEFACEZ_F_VERTEX_COUNT num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define CALCULATEFACEZ_COLUMNS num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define CALCULATEFACEZ_FACE_MIN_Z num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define CALCULATEFACEZ_FACE_MAX_Z num_var[10].nid_value.value[ num_var[10].byref_offset ] +#define CALCULATEFACEZ_Z_AVG num_var[11].nid_value.value[ num_var[11].byref_offset ] +#define FN_SetChannelSpacePosition 454 +#define SETCHANNELSPACEPOSITION_CHANNEL num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SETCHANNELSPACEPOSITION_ANGLE num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define SETCHANNELSPACEPOSITION_DISTANCE num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_SaveBMP 455 +#define SAVEBMP_IMG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SAVEBMP_FILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_SavePNG 456 +#define SAVEPNG_IMG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SAVEPNG_FILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_SaveJPG 457 +#define SAVEJPG_IMG num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define SAVEJPG_FILE$ str_var[0].sid_value.value[ str_var[0].byref_offset ] +#define FN_GetLineIntersection 458 +#define GETLINEINTERSECTION_P0_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETLINEINTERSECTION_P0_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETLINEINTERSECTION_P1_X num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETLINEINTERSECTION_P1_Y num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETLINEINTERSECTION_P2_X num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define GETLINEINTERSECTION_P2_Y num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define GETLINEINTERSECTION_P3_X num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define GETLINEINTERSECTION_P3_Y num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define GETLINEINTERSECTION_I_X num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define GETLINEINTERSECTION_I_Y num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define FN_Interpolate 459 +#define INTERPOLATE_MIN_A num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define INTERPOLATE_MAX_A num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define INTERPOLATE_MID_A num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define INTERPOLATE_MIN_B num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define INTERPOLATE_MAX_B num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_ATan2 460 +#define ATAN2_Y num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define ATAN2_X num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define FN_PointInQuad 461 +#define POINTINQUAD_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define POINTINQUAD_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define POINTINQUAD_X1 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define POINTINQUAD_Y1 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define POINTINQUAD_X2 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define POINTINQUAD_Y2 num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define POINTINQUAD_X3 num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define POINTINQUAD_Y3 num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define POINTINQUAD_X4 num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define POINTINQUAD_Y4 num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define FN_PointInTri 462 +#define POINTINTRI_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define POINTINTRI_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define POINTINTRI_X1 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define POINTINTRI_Y1 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define POINTINTRI_X2 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define POINTINTRI_Y2 num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define POINTINTRI_X3 num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define POINTINTRI_Y3 num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define FN_Distance2D 463 +#define DISTANCE2D_X1 num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DISTANCE2D_Y1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DISTANCE2D_X2 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DISTANCE2D_Y2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define FN_Distance3D 464 +#define DISTANCE3D_X1 num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define DISTANCE3D_Y1 num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define DISTANCE3D_Z1 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define DISTANCE3D_X2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define DISTANCE3D_Y2 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define DISTANCE3D_Z2 num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define FN_GetCircleLineIntersection 465 +#define GETCIRCLELINEINTERSECTION_CIRCLE_X num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETCIRCLELINEINTERSECTION_CIRCLE_Y num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETCIRCLELINEINTERSECTION_RADIUS num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETCIRCLELINEINTERSECTION_X1 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETCIRCLELINEINTERSECTION_Y1 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define GETCIRCLELINEINTERSECTION_X2 num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define GETCIRCLELINEINTERSECTION_Y2 num_var[6].nid_value.value[ num_var[6].byref_offset ] +#define GETCIRCLELINEINTERSECTION_IX1 num_var[7].nid_value.value[ num_var[7].byref_offset ] +#define GETCIRCLELINEINTERSECTION_IY1 num_var[8].nid_value.value[ num_var[8].byref_offset ] +#define GETCIRCLELINEINTERSECTION_IX2 num_var[9].nid_value.value[ num_var[9].byref_offset ] +#define GETCIRCLELINEINTERSECTION_IY2 num_var[10].nid_value.value[ num_var[10].byref_offset ] +#define FN_GetLinePlaneIntersection 466 +#define GETLINEPLANEINTERSECTION_LINE_POINT num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define GETLINEPLANEINTERSECTION_LINE_DIRECTION num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define GETLINEPLANEINTERSECTION_PLANE_POINT_1 num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define GETLINEPLANEINTERSECTION_PLANE_POINT_2 num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define GETLINEPLANEINTERSECTION_PLANE_POINT_3 num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define GETLINEPLANEINTERSECTION_INTERSECTION num_var[5].nid_value.value[ num_var[5].byref_offset ] +#define FN_IncrementMatrixRows 467 +#define INCREMENTMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define INCREMENTMATRIXROWS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define INCREMENTMATRIXROWS_R num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define INCREMENTMATRIXROWS_NUM_ROWS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define INCREMENTMATRIXROWS_VALUE num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_IncrementMatrixColumns 468 +#define INCREMENTMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define INCREMENTMATRIXCOLUMNS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define INCREMENTMATRIXCOLUMNS_C num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define INCREMENTMATRIXCOLUMNS_NUM_COLS num_var[3].nid_value.value[ num_var[3].byref_offset ] +#define INCREMENTMATRIXCOLUMNS_VALUE num_var[4].nid_value.value[ num_var[4].byref_offset ] +#define FN_JoinMatrixRows 469 +#define JOINMATRIXROWS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define JOINMATRIXROWS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define JOINMATRIXROWS_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] +#define FN_JoinMatrixColumns 470 +#define JOINMATRIXCOLUMNS_MA num_var[0].nid_value.value[ num_var[0].byref_offset ] +#define JOINMATRIXCOLUMNS_MB num_var[1].nid_value.value[ num_var[1].byref_offset ] +#define JOINMATRIXCOLUMNS_MC num_var[2].nid_value.value[ num_var[2].byref_offset ] diff --git a/rcbasic_runtime/rc_geometry.h b/rcbasic_runtime/rc_geometry.h new file mode 100644 index 0000000..b9fa015 --- /dev/null +++ b/rcbasic_runtime/rc_geometry.h @@ -0,0 +1,822 @@ +#include "rc_matrix.h" +#include + +#ifndef RC_GEOMETRY_H_INCLUDED +#define RC_GEOMETRY_H_INCLUDED + + +// ------------------ 3D Transform Routines -------------------------------- + + +double CalculateFaceZ(double cam_dist, double graph_offset_x, double graph_offset_y, double view_w, double view_h, double view_depth, uint32_t mA, int f_vertex_count, double* columns, double* face_min_z, double* face_max_z, double* z_avg) +{ + bool dbg = false; + + if(f_vertex_count > 4) + return -1; + + + double vx, vy, vz[4]; + + int oi_count = 0; + + + double n_face_min_z = MatrixValue(mA, 2, (uint32_t)columns[0]); + double n_face_max_z = n_face_min_z; + + + bool in_zx_range = false; + bool in_zy_range = false; + + double face_min_x = 0; + double face_max_x = 0; + + double face_min_y = 0; + double face_max_y = 0; + + bool zx_min_bound = false; + bool zx_max_bound = false; + + bool zy_min_bound = false; + bool zy_max_bound = false; + + double distance = 0; + + double z_dist = 0; //C3D_CAMERA_LENS - z + double off_x = graph_offset_x; + double off_y = graph_offset_y; + + double min_x = (0 - off_x) / cam_dist; + double min_y = (view_h - off_y) / cam_dist * -1; + + double max_x = (view_w - off_x) / cam_dist; + double max_y = (0 - off_y) / cam_dist * -1; + + double zx_min, zx_max, zy_min, zy_max; + + for(int i = 0; i < f_vertex_count; i++) + { + vz[i] = MatrixValue(mA, 2, (uint32_t)columns[i]); + vx = MatrixValue(mA, 0, (uint32_t)columns[i]); + vy = MatrixValue(mA, 1, (uint32_t)columns[i]); + + + distance = -1*vz[i]; + + if(distance >= 0 && distance < view_depth) + { + double d = cam_dist - (distance*-1); + zx_min = min_x * d; + zx_max = max_x * d; + zy_min = min_y * d; + zy_max = max_y * d; + + in_zx_range = in_zx_range || (vx >= zx_min && vx < zx_max); + in_zy_range = in_zy_range || (vy >= zy_min && vy < zy_max); + + zx_min_bound = zx_min_bound || (vx < zx_min); + zx_max_bound = zx_max_bound || (vx >= zx_max); + + zy_min_bound = zy_min_bound || (vy < zy_min); + zy_max_bound = zy_max_bound || (vy >= zy_max); + } + else if(vz[i] >= 0 && vz[i] < view_depth) + { + double d = cam_dist - (vz[i]*-1); + zx_min = min_x * d; + zx_max = max_x * d; + zy_min = min_y * d; + zy_max = max_y * d; + + in_zx_range = in_zx_range || (vx >= zx_min && vx < zx_max); + in_zy_range = in_zy_range || (vy >= zy_min && vy < zy_max); + + zx_min_bound = zx_min_bound || (vx < zx_min); + zx_max_bound = zx_max_bound || (vx >= zx_max); + + zy_min_bound = zy_min_bound || (vy < zy_min); + zy_max_bound = zy_max_bound || (vy >= zy_max); + } + + n_face_min_z = min(n_face_min_z, vz[i]); + n_face_max_z = max(n_face_max_z, vz[i]); + + } + + in_zx_range = in_zx_range || (zx_min_bound && zx_max_bound); + in_zy_range = in_zy_range || (zy_min_bound && zy_max_bound); + + if( (!in_zx_range) || (!in_zy_range) ) + return -1; + + //'if key(k_i) and actor = 1 then : print "face = ";face_num : end if + + z_avg[0] = (n_face_min_z+n_face_max_z) / 2; //'This is some bullshit math to order the faces with out checking if they are obscured + + face_min_z[0] = n_face_min_z; + face_max_z[0] = n_face_max_z; + + //C3D_Actor_Face_ZOrder[actor, face_num] = face_min_z + + + if(face_min_z[0] >= cam_dist) + return -1; + else + return (cam_dist - face_min_z[0]); + + +} + + + +int GetLinePlaneIntersection(double* line_point, double* line_direction, double* plane_point_1, double* plane_point_2, double* plane_point_3, double* intersection) +{ + //' """ + //' Calculates the intersection point of a line and a plane in 3D space. + //' + //' Parameters: + //' line_point (tuple or list): a point on the line (x, y, z) + //' line_direction (tuple or list): the direction vector of the line (x, y, z) + //' plane_point_1 (tuple or list): one point on the plane (x, y, z) + //' plane_point_2 (tuple or list): another point on the plane (x, y, z) + //' plane_point_3 (tuple or list): a third point on the plane (x, y, z) + //' + //' Returns: + //' intersection (tuple): the intersection point (x, y, z), or None if the line is parallel to the plane + //' """ + //' # calculate the normal vector of the plane using the cross product of two vectors on the plane + + double plane_vector_1[3], plane_vector_2[3], plane_normal[3]; + + plane_vector_1[0] = plane_point_2[0] - plane_point_1[0]; + plane_vector_1[1] = plane_point_2[1] - plane_point_1[1]; + plane_vector_1[2] = plane_point_2[2] - plane_point_1[2]; + + plane_vector_2[0] = plane_point_3[0] - plane_point_1[0]; + plane_vector_2[1] = plane_point_3[1] - plane_point_1[1]; + plane_vector_2[2] = plane_point_3[2] - plane_point_1[2]; + + plane_normal[0] = plane_vector_1[1] * plane_vector_2[2] - plane_vector_1[2] * plane_vector_2[1]; + plane_normal[1] = plane_vector_1[2] * plane_vector_2[0] - plane_vector_1[0] * plane_vector_2[2]; + plane_normal[2] = plane_vector_1[0] * plane_vector_2[1] - plane_vector_1[1] * plane_vector_2[0]; + + //'# calculate the scalar value of t using the line equation + double t = ((plane_point_1[0] - line_point[0]) * plane_normal[0] + (plane_point_1[1] - line_point[1]) * plane_normal[1] + (plane_point_1[2] - line_point[2]) * plane_normal[2]); + //'print "t1 = ";t + t = t / (line_direction[0] * plane_normal[0] + line_direction[1] * plane_normal[1] + line_direction[2] * plane_normal[2]); + //'print "t2 = ";(line_direction[0] * plane_normal[0] + line_direction[1] * plane_normal[1] + line_direction[2] * plane_normal[2]) + + //'# calculate the intersection point using the line equation + intersection[0] = line_point[0] + t * line_direction[0]; + intersection[1] = line_point[1] + t * line_direction[1]; + intersection[2] = line_point[2] + t * line_direction[2]; + + //'# check if the intersection point is on the plane + double plane_distance = abs((intersection[0] - plane_point_1[0]) * plane_normal[0] + (intersection[1] - plane_point_1[1]) * plane_normal[1] + (intersection[2] - plane_point_1[2]) * plane_normal[2]); + if(plane_distance < 10^-6) + return true; + else + return false; + +} + +double Distance3D(double x1, double y1, double z1, double x2, double y2, double z2) +{ + return sqrt( pow((x2 - x1),2) + pow((y2 - y1),2) + pow((z2 - z1),2) ); +} + +double Interpolate(double min_a, double max_a, double mid_a, double min_b, double max_b) +{ + return ( (mid_a-min_a)/(max_a-min_a)) * (max_b-min_b) + min_b; +} + + + +int GetLineIntersect(double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y, double* i_x, double* i_y) +{ + double s1_x = p1_x - p0_x; + double s1_y = p1_y - p0_y; + double s2_x = p3_x - p2_x; + double s2_y = p3_y - p2_y; + + double n = ( (-1 * s2_x) * s1_y + s1_x * s2_y); + + if(n == 0) + return 0; + + double s = ( (-1 * s1_y) * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / n; + double t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / n; + + i_x[0] = p0_x + (t * s1_x); + i_y[0] = p0_y + (t * s1_y); + + if(s >= 0 && s <= 1 && t >= 0 && t <= 1) + { + //' Collision detected + return 1; + } + + //' No collision + return 0; +} + + +int PointInQuad(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) +{ + //'""" + //'Check if a point (x, y) is inside a quadrilateral defined by its four vertices (x1, y1), (x2, y2), (x3, y3), and (x4, y4). + //'""" + //'# Compute the cross products of vectors from the point to each vertex of the quadrilateral. + //'# If all cross products have the same sign, the point is inside the quadrilateral. + double cross1 = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1); + double cross2 = (x - x2) * (y3 - y2) - (y - y2) * (x3 - x2); + double cross3 = (x - x3) * (y4 - y3) - (y - y3) * (x4 - x3); + double cross4 = (x - x4) * (y1 - y4) - (y - y4) * (x1 - x4); + + if(cross1 >= 0 && cross2 >= 0 && cross3 >= 0 && cross4 >= 0) + return 1; + else if(cross1 <= 0 && cross2 <= 0 && cross3 <= 0 && cross4 <= 0) + return 1; + else + return 0; +} + + +int PointInTri(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3) +{ + //""" + //Check if a point (x, y) is inside a triangle defined by its three vertices (x1, y1), (x2, y2), and (x3, y3). + //""" + //# Calculate the barycentric coordinates of the point with respect to the triangle vertices. + double denominator = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3); + + double alpha = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / denominator; + double beta = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / denominator; + double gamma = 1 - alpha - beta; + + //# Check if the barycentric coordinates are within the range [0, 1]. + if( (0 <= alpha && alpha <= 1) && (0 <= beta && beta <= 1) && (0 <= gamma && gamma <= 1) ) + return 1; + else + return 0; +} + + +double Distance2D(double x1, double y1, double x2, double y2) +{ + return sqrt( pow((x2 - x1),2) + pow((y2 - y1),2) ); +} + +double GetCircleLineIntersection(double cx, double cy, double r, double x1, double y1, double x2, double y2, double* ix1, double* iy1, double* ix2, double* iy2) +{ + //'""" + //'Calculate the intersection points between a line defined by two points (x1, y1) and (x2, y2), + //'and a circle with center (cx, cy) and radius r. + //'""" + double dx = x2 - x1; + double dy = y2 - y1; + double a = pow(dx,2) + pow(dy,2); + double b = 2 * (dx * (x1 - cx) + dy * (y1 - cy)); + double c = pow((x1 - cx),2) + pow((y1 - cy),2) - pow(r,2); + + double discriminant = pow(b,2) - 4 * a * c; + + if(discriminant < 0) + { + //'# No intersection points + return 0; + } + else if( discriminant == 0 ) + { + //'# One intersection point + double t = -b / (2 * a); + ix1[0] = x1 + t * dx; + iy1[0] = y1 + t * dy; + return 1; + } + else + { + //'# Two intersection points + double t1 = (-b + sqrt(discriminant)) / (2 * a); + double t2 = (-b - sqrt(discriminant)) / (2 * a); + + ix1[0] = x1 + t1 * dx; + iy1[0] = y1 + t1 * dy; + ix2[0] = x1 + t2 * dx; + iy2[0] = y1 + t2 * dy; + + return 2; + } +} + + + +int CAMERA_LENS = 0; + +// 'Returns number of points in clipped triangle Or 0 if no clipping was done +int ClipTriangle(double* tri, double* uv, double* clipped_tri, double* clipped_uv) +{ + + int clip_count = 0; + + double lp[3], ld[3], p1[3], p2[3], p3[3], intersect[3]; + + double AB_dist, AC_dist, dist; + + //'vec(lp, 20, 30, 265) + //'vec(ld, 20 - lp[0], 20 - lp[1], 275 - lp[2]) + + int clip_dist = CAMERA_LENS-1; + + p1[0] = -1; + p1[1] = -1; + p1[2] = clip_dist; + + p2[0] = 1; + p2[1] = 1; + p2[2] = clip_dist; + + p3[0] = 1; + p3[1] = -1; + p3[2] = clip_dist; + + //'C3D_LinePlaneIntersection(lp, ld, p1, p2, p3, intersect) + + double pt[9]; + double pt_uv[6]; + + double nc[9]; + double nc_uv[6]; + int non_clip_count = 0; + + int c_index = 0; + int pt_uv_index = 0; + int nc_uv_index = 0; + int uv_index = 0; + + for(int i = 0; i <= 8; i+=3) + { + if( tri[i+2] >= clip_dist ) + { + c_index = clip_count*3; + pt[c_index] = tri[i]; + pt[c_index+1] = tri[i+1]; + pt[c_index+2] = tri[i+2]; + + pt_uv_index = clip_count*2; + uv_index = i/3*2; + pt_uv[pt_uv_index] = uv[uv_index]; + pt_uv[pt_uv_index+1] = uv[uv_index+1]; + + clip_count = clip_count + 1; + } + else + { + c_index = non_clip_count*3; + nc[c_index] = tri[i]; + nc[c_index+1] = tri[i+1]; + nc[c_index+2] = tri[i+2]; + + nc_uv_index = non_clip_count*2; + uv_index = i/3*2; + nc_uv[nc_uv_index] = uv[uv_index]; + nc_uv[nc_uv_index+1] = uv[uv_index+1]; + + non_clip_count = non_clip_count + 1; + } + } + + if(clip_count == 0 || clip_count == 3 ) + { + return 0; + } + + + switch(clip_count) + { + case 1: + lp[0] = pt[0]; + lp[1] = pt[1]; + lp[2] = pt[2]; + + ld[0] = nc[0] - lp[0]; + ld[1] = nc[1] - lp[1]; + ld[2] = nc[2] - lp[2]; + + GetLinePlaneIntersection(&lp[0], &ld[0], &p1[0], &p2[0], &p3[0], &intersect[0]); + + //'dim clipped_tri[3] + + AB_dist = Distance3D(pt[0], pt[1], pt[2], nc[0], nc[1], nc[2]); + AC_dist = Distance3D(pt[0], pt[1], pt[2], nc[3], nc[4], nc[5]); + + //'AB + clipped_tri[0] = intersect[0]; + clipped_tri[1] = intersect[1]; + clipped_tri[2] = intersect[2]; + + dist = Distance3D(pt[0], pt[1], pt[2], clipped_tri[0], clipped_tri[1], clipped_tri[2]); + clipped_uv[0] = Interpolate(0, AB_dist, dist, pt_uv[0], nc_uv[0]); + clipped_uv[1] = Interpolate(0, AB_dist, dist, pt_uv[1], nc_uv[1]); + + //'B + clipped_tri[3] = nc[0]; + clipped_tri[4] = nc[1]; + clipped_tri[5] = nc[2]; + + clipped_uv[2] = nc_uv[0]; + clipped_uv[3] = nc_uv[1]; + //'print "TEST: ";clipped_uv[2];", ";clipped_uv[3] + + //'C + clipped_tri[6] = nc[3]; + clipped_tri[7] = nc[4]; + clipped_tri[8] = nc[5]; + + clipped_uv[4] = nc_uv[2]; + clipped_uv[5] = nc_uv[3]; + + //'print "TEST(C): (";clipped_tri[6];", ";clipped_tri[7];", ";clipped_tri[8];") (";clipped_uv[4];", ";clipped_uv[5];")" + + //'AB + clipped_tri[9] = clipped_tri[0]; + clipped_tri[10] = clipped_tri[1]; + clipped_tri[11] = clipped_tri[2]; + + clipped_uv[6] = clipped_uv[0]; + clipped_uv[7] = clipped_uv[1]; + + //'C + clipped_tri[12] = nc[3]; + clipped_tri[13] = nc[4]; + clipped_tri[14] = nc[5]; + + clipped_uv[8] = nc_uv[2]; + clipped_uv[9] = nc_uv[3]; + + ld[0] = nc[3] - lp[0]; + ld[1] = nc[4] - lp[1]; + ld[2] = nc[5] - lp[2]; + + GetLinePlaneIntersection(&lp[0], &ld[0], &p1[0], &p2[0], &p3[0], &intersect[0]); + + //'AC + clipped_tri[15] = intersect[0]; + clipped_tri[16] = intersect[1]; + clipped_tri[17] = intersect[2]; + + dist = Distance3D(pt[0], pt[1], pt[2], clipped_tri[15], clipped_tri[16], clipped_tri[17]); + clipped_uv[10] = Interpolate(0, AC_dist, dist, pt_uv[0], nc_uv[2]); + clipped_uv[11] = Interpolate(0, AC_dist, dist, pt_uv[1], nc_uv[3]); + + return 6; + + case 2: + //'A is the no clip + lp[0] = pt[0]; + lp[1] = pt[1]; + lp[2] = pt[2]; + + ld[0] = nc[0] - lp[0]; + ld[1] = nc[1] - lp[1]; + ld[2] = nc[2] - lp[2]; + + GetLinePlaneIntersection(&lp[0], &ld[0], &p1[0], &p2[0], &p3[0], &intersect[0]); + + AB_dist = Distance3D(pt[0], pt[1], pt[2], nc[0], nc[1], nc[2]); + AC_dist = Distance3D(pt[3], pt[4], pt[5], nc[0], nc[1], nc[2]); + + //'A + clipped_tri[0] = nc[0]; + clipped_tri[1] = nc[1]; + clipped_tri[2] = nc[2]; + + clipped_uv[0] = nc_uv[0]; + clipped_uv[1] = nc_uv[1]; + + //'AB + clipped_tri[3] = intersect[0]; + clipped_tri[4] = intersect[1]; + clipped_tri[5] = intersect[2]; + + dist = Distance3D(nc[0], nc[1], nc[2], clipped_tri[3], clipped_tri[4], clipped_tri[5]); + clipped_uv[2] = Interpolate(0, AB_dist, dist, nc_uv[0], pt_uv[0]); + clipped_uv[3] = Interpolate(0, AB_dist, dist, nc_uv[1], pt_uv[1]); + + //'AC + lp[0] = pt[3]; + lp[1] = pt[4]; + lp[2] = pt[5]; + + ld[0] = nc[0] - lp[0]; + ld[1] = nc[1] - lp[1]; + ld[2] = nc[2] - lp[2]; + + GetLinePlaneIntersection(&lp[0], &ld[0], &p1[0], &p2[0], &p3[0], &intersect[0]); + + clipped_tri[6] = intersect[0]; + clipped_tri[7] = intersect[1]; + clipped_tri[8] = intersect[2]; + + dist = Distance3D(nc[0], nc[1], nc[2], clipped_tri[6], clipped_tri[7], clipped_tri[8]); + clipped_uv[4] = Interpolate(0, AC_dist, dist, nc_uv[0], pt_uv[2]); + clipped_uv[5] = Interpolate(0, AC_dist, dist, nc_uv[1], pt_uv[3]); + + + return 3; + } + + return 0; + +} + + +void projectionGeometry(int cam_dist, int f_vertex_count, double* vertex3D, double* uv, double graph_offset_x, double graph_offset_y, uint32_t color, + double* vertex_count, double* vertex2D, double* ind_count, double* index, double* clip_dist, double* min_x, double* min_y, double* max_x, double* max_y) +{ + CAMERA_LENS = cam_dist; + + if( f_vertex_count > 4 || f_vertex_count < 3) + return; + + int tri_index = 0; + int uv_index = 0; + + int clip = 0; + + double clipped_tri[18], clipped_uv[12]; + double distance = 0; + double cld = 0; + int vi = 0; + uint32_t r, g, b, a; + r = ( (color >> 16) & 255); + g = ( (color >> 8) & 255); + b = ( color & 255); + a = ( (color >> 24) & 255); + + //cout << "color = " << color << ", " << r << ", " << g << ", " << b << ", " << a << endl; + + int index_count = 0; + vertex_count[0] = 0; + + int ni = 0; + + switch(f_vertex_count) + { + case 3: + clip = ClipTriangle(&vertex3D[0], &uv[0], &clipped_tri[0], &clipped_uv[0]); + if(clip > 0) + { + tri_index = 0; + uv_index = 0; + + for(int i = 0; i < clip; i++) + { + distance = CAMERA_LENS - clipped_tri[tri_index+2]; + distance = (distance <= 0) ? 1 : distance; + cld = (CAMERA_LENS / distance); + ni = vi * 8; + vertex2D[ ni + 0 ] = (cld * clipped_tri[tri_index]) + graph_offset_x; + vertex2D[ ni + 1 ] = graph_offset_y - (cld * clipped_tri[tri_index+1]); + vertex2D[ ni + 2 ] = r; + vertex2D[ ni + 3 ] = g; + vertex2D[ ni + 4 ] = b; + vertex2D[ ni + 5 ] = a; + vertex2D[ ni + 6 ] = clipped_uv[uv_index]; //' uv_x + (uv_w * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 0]) 'u + vertex2D[ ni + 7 ] = clipped_uv[uv_index+1]; //'uv_y + (uv_h * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 1]) 'v + + clip_dist[0] = min(distance, clip_dist[0]); + min_x[0] = min(vertex2D[ ni + 0], min_x[0]); + min_y[0] = min(vertex2D[ ni + 1], min_y[0]); + max_x[0] = max(vertex2D[ ni + 0], max_x[0]); + max_y[0] = max(vertex2D[ ni + 1], max_y[0]); + + index[index_count] = vi; + index_count = index_count + 1; + vi = vi + 1; + tri_index = tri_index + 3; + uv_index = uv_index + 2; + } + } + else + { + tri_index = 0; + uv_index = 0; + + for(int i = 0; i < 3; i++) + { + distance = CAMERA_LENS - vertex3D[tri_index+2]; + distance = (distance<=0) ? 1 : distance; + cld = (CAMERA_LENS / distance); + ni = vi * 8; + vertex2D[ ni + 0 ] = (cld * vertex3D[tri_index]) + graph_offset_x; + vertex2D[ ni + 1 ] = graph_offset_y - (cld * vertex3D[tri_index+1]); + vertex2D[ ni + 2 ] = r; + vertex2D[ ni + 3 ] = g; + vertex2D[ ni + 4 ] = b; + vertex2D[ ni + 5 ] = a; + vertex2D[ ni + 6 ] = uv[uv_index]; //' uv_x + (uv_w * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 0]) 'u + vertex2D[ ni + 7 ] = uv[uv_index+1]; //'uv_y + (uv_h * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 1]) 'v + + clip_dist[0] = min(distance, clip_dist[0]); + min_x[0] = min(vertex2D[ ni + 0], min_x[0]); + min_y[0] = min(vertex2D[ ni + 1], min_y[0]); + max_x[0] = max(vertex2D[ ni + 0], max_x[0]); + max_y[0] = max(vertex2D[ ni + 1], max_y[0]); + + vi = vi + 1; + tri_index = tri_index + 3; + uv_index = uv_index + 2; + } + + index[index_count] = 0; + index[index_count+1] = 1; + index[index_count+2] = 2; + index_count = index_count + 3; + } + break; + case 4: + clip = ClipTriangle(&vertex3D[0], &uv[0], &clipped_tri[0], &clipped_uv[0]); + if(clip > 0) + { + tri_index = 0; + uv_index = 0; + + for(int i = 0; i < clip; i++) + { + distance = CAMERA_LENS - clipped_tri[tri_index+2]; + distance = (distance<=0) ? 1 : distance; + cld = (CAMERA_LENS / distance); + ni = vi * 8; + vertex2D[ ni + 0 ] = (cld * clipped_tri[tri_index]) + graph_offset_x; + vertex2D[ ni + 1 ] = graph_offset_y - (cld * clipped_tri[tri_index+1]); + vertex2D[ ni + 2 ] = r; + vertex2D[ ni + 3 ] = g; + vertex2D[ ni + 4 ] = b; + vertex2D[ ni + 5 ] = a; + vertex2D[ ni + 6 ] = clipped_uv[uv_index]; //' uv_x + (uv_w * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 0]) 'u + vertex2D[ ni + 7 ] = clipped_uv[uv_index+1]; //'uv_y + (uv_h * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 1]) 'v + + clip_dist[0] = min(distance, clip_dist[0]); + min_x[0] = min(vertex2D[ ni + 0], min_x[0]); + min_y[0] = min(vertex2D[ ni + 1], min_y[0]); + max_x[0] = max(vertex2D[ ni + 0], max_x[0]); + max_y[0] = max(vertex2D[ ni + 1], max_y[0]); + + index[index_count] = vi; + index_count = index_count + 1; + vi = vi + 1; + tri_index = tri_index + 3; + uv_index = uv_index + 2; + } + } + else + { + //cout << "DBG: " << vertex3D[0] << ", " << vertex3D[1] << endl; + tri_index = 0; + uv_index = 0; + + for(int i = 0; i < 3; i++) + { + distance = CAMERA_LENS - vertex3D[tri_index+2]; + distance = (distance<=0) ? 1 : distance; + cld = (CAMERA_LENS / distance); + ni = vi * 8; + vertex2D[ ni + 0 ] = (cld * vertex3D[tri_index]) + graph_offset_x; + vertex2D[ ni + 1 ] = graph_offset_y - (cld * vertex3D[tri_index+1]); + vertex2D[ ni + 2 ] = r; + vertex2D[ ni + 3 ] = g; + vertex2D[ ni + 4 ] = b; + vertex2D[ ni + 5 ] = a; + vertex2D[ ni + 6 ] = uv[uv_index]; //' uv_x + (uv_w * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 0]) 'u + vertex2D[ ni + 7 ] = uv[uv_index+1]; //'uv_y + (uv_h * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 1]) 'v + + clip_dist[0] = min(distance, clip_dist[0]); + min_x[0] = min(vertex2D[ ni + 0], min_x[0]); + min_y[0] = min(vertex2D[ ni + 1], min_y[0]); + max_x[0] = max(vertex2D[ ni + 0], max_x[0]); + max_y[0] = max(vertex2D[ ni + 1], max_y[0]); + + vi = vi + 1; + tri_index = tri_index + 3; + uv_index = uv_index + 2; + } + + index[index_count] = 0; + index[index_count+1] = 1; + index[index_count+2] = 2; + index_count = index_count + 3; + } + + vertex3D[3] = vertex3D[0]; + vertex3D[4] = vertex3D[1]; + vertex3D[5] = vertex3D[2]; + + uv[2] = uv[0]; + uv[3] = uv[1]; + clip = ClipTriangle(&vertex3D[3], &uv[2], &clipped_tri[0], &clipped_uv[0]); + + if(clip > 0) + { + tri_index = 0; + uv_index = 0; + + for(int i = 0; i < clip; i++) + { + distance = CAMERA_LENS - clipped_tri[tri_index+2]; + distance = (distance<=0) ? 1 : distance; + cld = (CAMERA_LENS / distance); + ni = vi * 8; + vertex2D[ ni + 0 ] = (cld * clipped_tri[tri_index]) + graph_offset_x; + vertex2D[ ni + 1 ] = graph_offset_y - (cld * clipped_tri[tri_index+1]); + vertex2D[ ni + 2 ] = r; + vertex2D[ ni + 3 ] = g; + vertex2D[ ni + 4 ] = b; + vertex2D[ ni + 5 ] = a; + vertex2D[ ni + 6 ] = clipped_uv[uv_index]; //' uv_x + (uv_w * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 0]) 'u + vertex2D[ ni + 7 ] = clipped_uv[uv_index+1]; //'uv_y + (uv_h * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 1]) 'v + + clip_dist[0] = min(distance, clip_dist[0]); + min_x[0] = min(vertex2D[ ni + 0], min_x[0]); + min_y[0] = min(vertex2D[ ni + 1], min_y[0]); + max_x[0] = max(vertex2D[ ni + 0], max_x[0]); + max_y[0] = max(vertex2D[ ni + 1], max_y[0]); + + index[index_count] = vi; + index_count = index_count + 1; + + vi = vi + 1; + + tri_index = tri_index + 3; + uv_index = uv_index + 2; + } + } + else + { + tri_index = 3; + uv_index = 2; + + for(int i = 0; i < 3; i++) + { + distance = CAMERA_LENS - vertex3D[tri_index+2]; + distance = (distance<=0) ? 1 : distance; + cld = (CAMERA_LENS / distance); + ni = vi * 8; + vertex2D[ ni + 0 ] = (cld * vertex3D[tri_index]) + graph_offset_x; + vertex2D[ ni + 1 ] = graph_offset_y - (cld * vertex3D[tri_index+1]); + vertex2D[ ni + 2 ] = r; + vertex2D[ ni + 3 ] = g; + vertex2D[ ni + 4 ] = b; + vertex2D[ ni + 5 ] = a; + vertex2D[ ni + 6 ] = uv[uv_index]; //' uv_x + (uv_w * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 0]) 'u + vertex2D[ ni + 7 ] = uv[uv_index+1]; //'uv_y + (uv_h * C3D_Mesh_TCoord[mesh, C3D_Mesh_Face_TCoord[mesh, face, i], 1]) 'v + + clip_dist[0] = min(distance, clip_dist[0]); + min_x[0] = min(vertex2D[ ni + 0], min_x[0]); + min_y[0] = min(vertex2D[ ni + 1], min_y[0]); + max_x[0] = max(vertex2D[ ni + 0], max_x[0]); + max_y[0] = max(vertex2D[ ni + 1], max_y[0]); + + index[index_count] = vi; //'They will already be in the right order here + index_count = index_count + 1; + vi = vi + 1; + tri_index = tri_index + 3; + uv_index = uv_index + 2; + } + + } + break; + + } + + vertex_count[0] = (double)vi; + ind_count[0] = (double)index_count; + + //cout << "DEBUG: " << vertex_count[0] << ", " << ind_count[0] << endl; + +} + + +void rc_GetProjectionGeometry(int cam_dist, uint32_t mA, int f_vertex_count, double* columns, double* uv, double graph_offset_x, double graph_offset_y, uint32_t color, + double* vertex_count, double* vertex2D, double* ind_count, double* index, double* clip_dist, double* min_x, double* min_y, double* max_x, double* max_y) +{ + double vertex3D[18]; // number of vertices * 3 -> ie. (x,y,z) for each vertex + + int v_index = 0; + for(int i = 0; i < f_vertex_count; i++) + { + vertex3D[v_index] = MatrixValue(mA, 0, columns[i]); + vertex3D[v_index+1] = MatrixValue(mA, 1, columns[i]); + vertex3D[v_index+2] = MatrixValue(mA, 2, columns[i]); + v_index += 3; + } + + projectionGeometry(cam_dist, f_vertex_count, &vertex3D[0], uv, graph_offset_x, graph_offset_y, color, + vertex_count, vertex2D, ind_count, index, clip_dist, min_x, min_y, max_x, max_y); +} + + +// -------------------------------------------------------------------------- + + +#endif // RC_GEOMETRY_H_INCLUDED diff --git a/rcbasic_runtime/rc_matrix.h b/rcbasic_runtime/rc_matrix.h new file mode 100644 index 0000000..817f575 --- /dev/null +++ b/rcbasic_runtime/rc_matrix.h @@ -0,0 +1,1189 @@ +#ifndef RC_MATRIX_H_INCLUDED +#define RC_MATRIX_H_INCLUDED + +#include +#include +#ifndef RC_WEB +#ifndef RC_ANDROID +#ifndef RC_IOS + #include +#endif +#endif +#endif +#include +#include + +using namespace std; + + +int64_t rand_int(int64_t vmin, int64_t vmax) { + return std::rand() % (vmax - vmin + 1) + vmin; +} + + +struct rc_matrix_type +{ + uint32_t r = 0; + uint32_t c = 0; + vector data; +}; + +rc_matrix_type rc_matrix[1048]; + +#define RC_TMP_MATRIX 1024 +#define RC_TMP_MATRIX_2 1025 + +#define RC_PROCESS_TMP_MATRIX_OFFSET 1026 + +void DimMatrix(int m, uint32_t m_rows, uint32_t m_cols, bool preserve_flag=false) +{ + rc_matrix[m].data.resize(m_rows*m_cols); + + if(rc_matrix[m].c != m_cols && preserve_flag) + { + vector old_data = rc_matrix[m].data; + uint32_t old_offset = 0; + uint32_t new_offset = 0; + for(uint32_t row = 0; row < m_rows; row++) + { + old_offset = row * rc_matrix[m].c; + new_offset = row * m_cols; + for(uint32_t col = 0; col < m_cols; col++) + { + rc_matrix[m].data[new_offset + col] = old_data[old_offset + col]; + } + } + } + + rc_matrix[m].r = m_rows; + rc_matrix[m].c = m_cols; +} + +//Adds Matrix A() to Matrix B(), answer is Matrix C() +bool AddMatrix(int mA, int mB, int mC) +{ + if( (rc_matrix[mA].r != rc_matrix[mB].r) || (rc_matrix[mA].c != rc_matrix[mB].c) ) + { + std::cout << "AddMatrix Error: Matrix sizes don't match" << std::endl; + return false; + } + + DimMatrix(mC, rc_matrix[mA].r, rc_matrix[mA].c); + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mC].data[ row_offset + col ] = rc_matrix[mA].data[ row_offset + col] + rc_matrix[mB].data[ row_offset + col]; + } + } + + return true; +} + +//Concatenates matrix A() and B(), output is matrix C() +bool AugmentMatrix (int mA, int mB, int mC) +{ + if(rc_matrix[mA].r != rc_matrix[mB].r) + { + std::cout << "AugmentMatrix Error: Row Counts don't match" << std::endl; + return false; + } + + DimMatrix(mC, rc_matrix[mA].r, rc_matrix[mA].c + rc_matrix[mB].c); + + uint32_t row_offset = 0; + uint32_t ab_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + ab_offset = row * rc_matrix[mA].c; + row_offset = row * rc_matrix[mC].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mC].data[ row_offset + col ] = rc_matrix[mA].data[ ab_offset + col ]; + } + } + + for(uint32_t row = 0; row < rc_matrix[mB].r; row++) + { + ab_offset = row * rc_matrix[mB].c; + row_offset = row * rc_matrix[mC].c; + for(uint32_t col = 0; col < rc_matrix[mB].c; col++) + { + rc_matrix[mC].data[ row_offset + col + rc_matrix[mA].c] = rc_matrix[mB].data[ ab_offset + col ]; + } + } + + return true; +} + +//Copies contents of matrix A() to B() +void CopyMatrix(int mA, int mB) +{ + DimMatrix(mB, rc_matrix[mA].r, rc_matrix[mA].c); + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mB].data[row_offset + col] = rc_matrix[mA].data[row_offset + col]; + } + } +} + +//Inserts specified number of columns in matrix A before c and shifts values to the right +bool InsertMatrixColumn(int mA, uint32_t c, uint32_t num_cols) +{ + if(c >= rc_matrix[mA].c) + { + std::cout << "InsertMatrixColumn Error: Can't insert past the last column" << std::endl; + return false; + } + + vector old_data = rc_matrix[mA].data; + uint32_t old_c = rc_matrix[mA].c; + uint32_t old_r = rc_matrix[mA].r; + + DimMatrix(mA, rc_matrix[mA].r, rc_matrix[mA].c + num_cols); + + uint32_t old_offset = 0; + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + old_offset = row * old_c; + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + if(col >= c) + { + if(col < (c+num_cols)) + rc_matrix[mA].data[row_offset + col] = 0; + + if(col < old_c) + rc_matrix[mA].data[row_offset + col + num_cols] = old_data[old_offset + col]; + } + else + rc_matrix[mA].data[row_offset + col] = old_data[old_offset + col]; + } + } + + return true; +} + +//Creates new zero row M% in matrix A(), moves values down +bool InsertMatrixRow (int mA, uint32_t r, uint32_t num_rows) +{ + if(r >= rc_matrix[mA].r) + { + std::cout << "InsertMatrixRow Error: Can't insert past the last row" << std::endl; + return false; + } + + DimMatrix(mA, rc_matrix[mA].r + num_rows, rc_matrix[mA].c); + + uint32_t row_offset = 0; + uint32_t new_offset = 0; + bool shift_row = true; + for(uint32_t row = r; row < (r + num_rows); row++) + { + row_offset = row * rc_matrix[mA].c; + if((row + num_rows) < rc_matrix[mA].r) + { + shift_row = true; + new_offset = (row+num_rows) * rc_matrix[mA].c; + } + else + shift_row = false; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + if(shift_row) + rc_matrix[mA].data[new_offset + col] = rc_matrix[mA].data[row_offset + col]; + rc_matrix[mA].data[row_offset + col] = 0; + } + } + + return true; +} + +//Multiplies Matrix A() with Matrix B(), answer is Matrix C() +bool MultiplyMatrix (int mA, int mB, int mC) +{ + if( rc_matrix[mA].c != rc_matrix[mB].r ) + { + std::cout << "MultiplyMatrix Error: matrix A rows and matrix B columns must be equal." << std::endl; + return false; + } + + DimMatrix( mC, rc_matrix[mA].r, rc_matrix[mB].c); + + double total = 0; + uint32_t a_offset = 0; + uint32_t b_offset = 0; + uint32_t c_offset = 0; + for(uint32_t a_row = 0; a_row < rc_matrix[mA].r; a_row++) //I + { + a_offset = a_row * rc_matrix[mA].c; + for(uint32_t b_col = 0; b_col < rc_matrix[mB].c; b_col++) //J + { + for(uint32_t a_col = 0; a_col < rc_matrix[mA].c; a_col++) //N + { + b_offset = a_col * rc_matrix[mB].c; + total = total + rc_matrix[mA].data[a_offset + a_col] * rc_matrix[mB].data[b_offset + b_col]; + } + c_offset = a_row * rc_matrix[mB].c; + rc_matrix[mC].data[c_offset + b_col] = total; + total = 0; + } + } + + return true; +} + +//Multiplies matrix A() * A() * A(), returns matrix B() +bool CubeMatrix(int mA, int mB, int process_num) +{ + if(rc_matrix[mA].r != rc_matrix[mA].c) + { + std::cout << "CubeMatrix Error: matrix A is not a square matrix." << std::endl; + return false; + } + + int tmp_mat1 = process_num < 0 ? RC_TMP_MATRIX : (process_num*2) + RC_PROCESS_TMP_MATRIX_OFFSET; + //int tmp_mat2 = process_num < 0 ? RC_TMP_MATRIX : (process_num*2) + RC_PROCESS_TMP_MATRIX_OFFSET + 1; + + DimMatrix(tmp_mat1, rc_matrix[mA].r, rc_matrix[mA].c); + MultiplyMatrix(mA, mA, tmp_mat1); + MultiplyMatrix(tmp_mat1, mA, mB); + + DimMatrix(tmp_mat1, 1, 1); + return true; +} + +// Deletes column N% from matrix +bool DeleteMatrixColumns(int mA, uint32_t c, uint32_t num_cols, int process_num) +{ + if(c >= rc_matrix[mA].c) + { + std::cout << "DeleteMatrixColumn Error: column is outside of matrix" << std::endl; + return false; + } + + if((c + num_cols) > rc_matrix[mA].c) + num_cols = rc_matrix[mA].c - c; + + int tmp_mat1 = process_num < 0 ? RC_TMP_MATRIX : (process_num*2) + RC_PROCESS_TMP_MATRIX_OFFSET; + //int tmp_mat2 = process_num < 0 ? RC_TMP_MATRIX : (process_num*2) + RC_PROCESS_TMP_MATRIX_OFFSET + 1; + + DimMatrix( tmp_mat1, rc_matrix[mA].r, rc_matrix[mA].c - num_cols); + + uint32_t old_offset = 0; + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + old_offset = row * rc_matrix[mA].c; + row_offset = row * rc_matrix[tmp_mat1].c; + for(uint32_t col = 0; col < rc_matrix[tmp_mat1].c; col++) + { + if(col >= c) + { + rc_matrix[tmp_mat1].data[row_offset + col] = rc_matrix[mA].data[old_offset + col + num_cols]; + } + else + rc_matrix[tmp_mat1].data[row_offset + col] = rc_matrix[mA].data[old_offset + col]; + } + } + CopyMatrix(tmp_mat1, mA); + DimMatrix(tmp_mat1, 1, 1); + return true; +} + +//Deletes row M% from matrix +bool DeleteMatrixRows(int mA, uint32_t r, uint32_t num_rows) +{ + if(r >= rc_matrix[mA].r) + { + std::cout << "DeleteMatrixRow Error: row is outside of matrix." << std::endl; + return false; + } + + if((r + num_rows) > rc_matrix[mA].r) + num_rows = rc_matrix[mA].r - r; + + uint32_t new_row_count = rc_matrix[mA].r - num_rows; + + uint32_t old_offset = 0; + uint32_t row_offset = 0; + + for(uint32_t row = r; row < new_row_count; row++) + { + row_offset = row * rc_matrix[mA].c; + old_offset = (row+num_rows) * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mA].data[row_offset + col] = rc_matrix[mA].data[old_offset + col]; + } + } + + DimMatrix( mA, rc_matrix[mA].r - num_rows, rc_matrix[mA].c); + + return true; +} + +//Clears contents of matrix A() +void ClearMatrix(int mA) +{ + for(int i = 0; i < rc_matrix[mA].data.size(); i++) + rc_matrix[mA].data[i] = 0; +} + +//Fills column J% of matrix A() with zeros +bool ClearMatrixColumns (int mA, uint32_t c, uint32_t num_cols) +{ + if(c >= rc_matrix[mA].c) + { + std::cout << "ClearMatrixColumn Error: column is outside of matrix A" << std::endl; + return false; + } + + if( (c+num_cols) > rc_matrix[mA].c) + num_cols = rc_matrix[mA].c - c; + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = c; col < (c+num_cols); col++) + rc_matrix[mA].data[row_offset + col] = 0; + } + + return true; +} + +// Fills row I% of matrix A() with zeros +bool ClearMatrixRows(int mA, uint32_t r, uint32_t num_rows) +{ + if(r >= rc_matrix[mA].r) + { + std::cout << "ClearMatrixRow Error: row is outside of matrix A" << std::endl; + return false; + } + + if((r + num_rows) > rc_matrix[mA].r) + num_rows = rc_matrix[mA].r - r; + + uint32_t row_offset = 0; + + for(uint32_t row = r; row < (r+num_rows); row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mA].data[row_offset + col] = 0; + } + } + + return true; +} + +// Fills matrix A() with value V +void FillMatrix(int mA, double v) +{ + for(uint32_t i = 0; i < rc_matrix[mA].data.size(); i++) + rc_matrix[mA].data[i] = v; +} + +// Fills matrix A() column J% with value V +bool FillMatrixColumns(int mA, uint32_t c, uint32_t num_cols, double v) +{ + if(c >= rc_matrix[mA].c) + { + std::cout << "FillMatrixColumns Error: column is outside of matrix A" << std::endl; + return false; + } + + if( (c+num_cols) >= rc_matrix[mA].c) + num_cols = rc_matrix[mA].c - c; + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = c; col < (c+num_cols); col++) + rc_matrix[mA].data[row_offset + col] = v; + } + + return true; +} + +// Fills matrix A() row I% with value V +bool FillMatrixRows(int mA, uint32_t r, uint32_t num_rows, double v) +{ + if(r >= rc_matrix[mA].r) + { + std::cout << "FillMatrixRows Error: row is outside of matrix A" << std::endl; + return false; + } + + if( (r+num_rows) > rc_matrix[mA].r) + num_rows = rc_matrix[mA].r - r; + + uint32_t row_offset = 0; + + for(uint32_t row = r; row < (r+num_rows); row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mA].data[row_offset + col] = v; + } + } + + return true; +} + +// Copies A() column J% to column matrix B() +bool GetMatrixColumns(uint32_t mA, uint32_t mB, uint32_t c, uint32_t num_cols) +{ + if(c >= rc_matrix[mA].c) + { + std::cout << "GetMatrixColumn Error: column outside of matrix A" << std::endl; + return false; + } + + if( (c+num_cols) >= rc_matrix[mA].c) + num_cols = rc_matrix[mA].c - c; + + DimMatrix(mB, rc_matrix[mA].r, num_cols); + + int row_offset = 0; + int b_offset = 0; + for(int row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + b_offset = row * num_cols; + for(uint32_t col = c; col < (c+num_cols); col++) + rc_matrix[mB].data[b_offset + (col-c)] = rc_matrix[mA].data[row_offset + c]; + } + + return true; +} + +// Copies A() row I% to row matrix B() +bool GetMatrixRows (uint32_t mA, uint32_t mB, uint32_t r, uint32_t num_rows) +{ + + if(r > rc_matrix[mA].r) + { + std::cout << "GetMatrixRow Error: row outside of matrix A" << std::endl; + return false; + } + + if( (r+num_rows) > rc_matrix[mA].r) + num_rows = rc_matrix[mA].r - r; + + DimMatrix( mB, num_rows, rc_matrix[mA].c); + + uint32_t row_offset = 0; + + for(uint32_t row = r; row < (r+num_rows); row++) + { + row_offset = row * rc_matrix[mA].c; + + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mB].data[row_offset + col] = rc_matrix[mA].data[row_offset + col]; + } + } + + return true; +} + +// Creates Identity Matrix A() of order N% +void IdentityMatrix(uint32_t mA, uint32_t n) +{ + DimMatrix(mA, n, n); + for(int i = 0; i < n; i++) + rc_matrix[mA].data[i*n+n] = 1; +} + +bool GaussianElimination(vector< vector > &A, vector &b, uint32_t mC) { + int n = b.size(); + + for (int p = 0; p < n; p++) { + int max_index = p; + for (int i = p + 1; i < n; i++) { + if (abs(A[i][p]) > abs(A[max_index][p])) { + max_index = i; + } + } + + swap(A[p], A[max_index]); + swap(b[p], b[max_index]); + + for (int i = p + 1; i < n; i++) { + if(A[p][p] == 0) + return false; + double alpha = A[i][p] / A[p][p]; + b[i] -= alpha * b[p]; + for (int j = p; j < n; j++) { + A[i][j] -= alpha * A[p][j]; + } + } + } + + vector x(n); + DimMatrix(mC, n, 1); + ClearMatrix(mC); + + for (int i = n - 1; i >= 0; i--) { + double sum = 0.0; + for (int j = i + 1; j < n; j++) { + sum += A[i][j] * rc_matrix[mC].data[j]; + } + if(A[i][i] == 0) + return false; + rc_matrix[mC].data[i] = (b[i] - sum) / A[i][i]; + } + + return true; +} + +// Solve the system that has A as coefficient matrix and B is the right hand side of the equation +// Solution will be stored in C +bool SolveMatrix(uint32_t mA, uint32_t mB, uint32_t mC) +{ + if(rc_matrix[mA].r != rc_matrix[mA].c || rc_matrix[mA].r != rc_matrix[mB].r || rc_matrix[mB].c != 1) + return false; + + vector< vector > A(rc_matrix[mA].r); + vector b; + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + A[row].push_back(rc_matrix[mA].data[row_offset + col]); + } + } + + for(int i = 0; i < rc_matrix[mB].data.size(); i++) + b.push_back(rc_matrix[mB].data[i]); + + return GaussianElimination(A, b, mC); +} + +double d_abs(double n) +{ + return (n < 0) ? n * -1 : n; +} + +//Determines if matrix A() is equal (within Tol constant) to matrix B() +bool IsEqualMatrix(uint32_t mA, uint32_t mB, double tolerance) +{ + if( (rc_matrix[mA].r != rc_matrix[mB].r) || (rc_matrix[mA].c != rc_matrix[mB].c) ) + return false; + + uint32_t row_offset = 0; + + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + if(d_abs( rc_matrix[mA].data[row_offset + col] - rc_matrix[mB].data[row_offset + col] ) > tolerance) + return false; + } + } + return true; +} + +// Function to get cofactor of A[p][q] in temp[][]. n is +// current dimension of A[][] +void getCofactor(uint32_t A_dim, double* A, double* temp, int p, int q, + int n) +{ + int i = 0, j = 0; + + // Looping for each element of the matrix + for (int row = 0; row < n; row++) { + for (int col = 0; col < n; col++) { + // Copying into temporary matrix only those + // element which are not in given row and + // column + if (row != p && col != q) { + temp[i*A_dim + j++] = A[row*A_dim + col]; + + // Row is filled, so increase row index and + // reset col index + if (j == n - 1) { + j = 0; + i++; + } + } + } + } +} + +bool CofactorMatrix(uint32_t mA, int p, int q, int n) +{ + + uint32_t m_size = rc_matrix[mA].c; + double temp[m_size*rc_matrix[mA].r]; + getCofactor(m_size, rc_matrix[mA].data.data(), temp, p, q, n); + DimMatrix(mA, m_size-1, m_size-1); + uint32_t row_offset = 0; + uint32_t temp_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + temp_offset = row * m_size; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mA].data[row_offset + col] = temp[temp_offset + col]; + } + } +} + +/* Recursive function for finding determinant of matrix. +n is current dimension of A[][]. */ +double determinant(double* A, int n, uint32_t m_size) +{ + double D = 0; // Initialize result + + // Base case : if matrix contains single element + if (n == 1) + return A[0]; + + double temp[m_size*m_size]; // To store cofactors + + int sign = 1; // To store sign multiplier + + // Iterate for each element of first row + for (int f = 0; f < n; f++) { + // Getting Cofactor of A[0][f] + getCofactor(m_size, A, temp, 0, f, n); + D += sign * A[f] * determinant(temp, n - 1, m_size); + + // terms are to be added with alternate sign + sign = -sign; + } + + return D; +} + +double Determinant(uint32_t mA) +{ + uint32_t m_size = rc_matrix[mA].r; + if(rc_matrix[mA].c != m_size) + { + cout << "Determinant Error: matrix must be square" << endl; + return false; + } + return determinant(rc_matrix[mA].data.data(), m_size, m_size); +} + + +// Function to get adjoint of A[N][N] in adj[N][N]. +void adjoint(double* A, double* adj, uint32_t n, uint32_t m_size) +{ + if (n == 1) { + adj[0] = 1; + return; + } + + // temp is used to store cofactors of A[][] + int sign = 1; + double temp[n*n]; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + // Get cofactor of A[i][j] + getCofactor(n, A, temp, i, j, n); + + // sign of adj[j][i] positive if sum of row + // and column indexes is even. + sign = ((i + j) % 2 == 0) ? 1 : -1; + + // Interchanging rows and columns to get the + // transpose of the cofactor matrix + adj[j*n+i] = (sign) * (determinant(temp, n - 1, m_size)); + } + } +} + +bool AdjointMatrix(uint32_t mA, uint32_t mB) +{ + uint32_t m_size = rc_matrix[mA].r; + if(rc_matrix[mA].c != m_size) + { + cout << "MatrixAdjoint Error: matrix must be square" << endl; + return false; + } + DimMatrix(mB, m_size, m_size); + adjoint(rc_matrix[mA].data.data(), rc_matrix[mB].data.data(), m_size, m_size); + return true; +} + +// Function to calculate and store inverse, returns false if +// matrix is singular +bool inverse(double* A, double* inv, uint32_t n) +{ + // Find determinant of A[][] + double det = determinant(A, n, n); + if (det == 0) { + return false; + } + + // Find adjoint + double adj[n*n]; + adjoint(A, adj, n, n); + + // Find Inverse using formula "inverse(A) = + // adj(A)/det(A)" + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + inv[i*n+j] = adj[i*n+j] / det; + + return true; +} + +bool InvertMatrix(uint32_t mA, uint32_t mB) +{ + uint32_t m_size = rc_matrix[mA].r; + if(rc_matrix[mA].c != m_size) + { + cout << "InvertMatrix Error: matrix must be square" << endl; + return false; + } + DimMatrix(mB, m_size, m_size); + if(!inverse(rc_matrix[mA].data.data(), rc_matrix[mB].data.data(), m_size)) + { + cout << "InvertMatrix Error: Singular matrix, can't find its inverse" << endl; + return false; + } + return true; +} + + +//Loads contents of FileName$ into matrix A() +void MatrixFromBuffer(uint32_t mA, uint32_t r, uint32_t c, double* buffer) +{ + uint32_t row_offset = 0; + DimMatrix(mA, r, c); + + for(uint32_t row = 0; row < r; row++) + { + row_offset = row*c; + for(uint32_t col = 0; col < c; col++) + { + rc_matrix[mA].data[row_offset + col] = buffer[row_offset + col]; + } + } +} + +//Loads contents of FileName$ into matrix A() +void BufferFromMatrix(double* buffer, uint32_t mA) +{ + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row*rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + buffer[row_offset + col] = rc_matrix[mA].data[row_offset + col]; + } + } +} + +//Fills matrix A() with random values ranging from VMin to VMax +void RandomizeMatrix(uint32_t mA, double vmin, double vmax) +{ + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mA].data[row_offset + col] = rand_int(vmin, vmax); + } + } +} + +//get value from matrix A +double MatrixValue(uint32_t mA, uint32_t r, uint32_t c) +{ + uint32_t pos = r*rc_matrix[mA].c + c; + if(pos >= rc_matrix[mA].data.size()) + return 0; + + return rc_matrix[mA].data[pos]; +} + +//set value at (r, c) in matrix +void SetMatrixValue(uint32_t mA, uint32_t r, uint32_t c, double v) +{ + uint32_t pos = r*rc_matrix[mA].c + c; + if(pos >= rc_matrix[mA].data.size()) + return; + + rc_matrix[mA].data[pos] = v; +} + +//Multiplies matrix A() by scalar, output matrix B() +void ScalarMatrix (uint32_t mA, uint32_t mB, double s_value) +{ + uint32_t row_offset = 0; + DimMatrix(mB, rc_matrix[mA].r, rc_matrix[mA].c); + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mB].data[row_offset + col] = s_value * rc_matrix[mA].data[row_offset + col]; + } + } +} + +// Multiplies matrix A() by scalar S at column J%, output matrix B() +bool ScalarMatrixColumns(uint32_t mA, uint32_t mB, uint32_t c, uint32_t num_cols, double s_value) +{ + if(c >= rc_matrix[mA].c) + { + std::cout << "ScalarMatrixColumn Error: column outside of matrix A" << std::endl; + return false; + } + + if( (c+num_cols) >= rc_matrix[mA].c) + num_cols = rc_matrix[mA].c - c; + + CopyMatrix(mA, mB); + + int row_offset = 0; + int b_offset = 0; + for(int row = 0; row < rc_matrix[mB].r; row++) + { + row_offset = row * rc_matrix[mB].c; + for(uint32_t col = c; col < (c+num_cols); col++) + rc_matrix[mB].data[row_offset + col] *= s_value; + } + + return true; +} + +//Multiplies matrix A() by scalar S at row I%, output matrix B() +bool ScalarMatrixRows(uint32_t mA, uint32_t mB, uint32_t r, uint32_t num_rows, double s_value) +{ + + if(r > rc_matrix[mA].r) + { + std::cout << "ScalarMatrixRows Error: row outside of matrix A" << std::endl; + return false; + } + + if( (r+num_rows) > rc_matrix[mA].r) + num_rows = rc_matrix[mA].r - r; + + CopyMatrix(mA, mB); + + uint32_t row_offset = 0; + + for(uint32_t row = r; row < (r+num_rows); row++) + { + row_offset = row * rc_matrix[mA].c; + + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mB].data[row_offset + col] = s_value * rc_matrix[mA].data[row_offset + col]; + } + } + + return true; +} + +// Multiplies matrix A() * A(), returns matrix B() +bool SquareMatrix(uint32_t mA, uint32_t mB) +{ + if(rc_matrix[mA].r != rc_matrix[mA].c) + { + std::cout << "SquareMatrix Error: must be a square matrix" << std::endl; + return false; + } + + return MultiplyMatrix(mA, mA, mB); +} + +// Deletes row r and column c from matrix A +void SubMatrix(uint32_t mA, uint32_t r, uint32_t c) +{ + CofactorMatrix(mA, r, c, rc_matrix[mA].c); +} + +// Subtracts Matrix B() from Matrix A(), answer is Matrix C() +bool SubtractMatrix (uint32_t mA, uint32_t mB, uint32_t mC) +{ + if(rc_matrix[mA].r != rc_matrix[mB].r || rc_matrix[mA].c != rc_matrix[mB].c) + { + std::cout << "SubtractMatrix Error: matrix A and B differ in size" << std::endl; + return false; + } + + DimMatrix(mC, rc_matrix[mA].r, rc_matrix[mA].c); + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + rc_matrix[mC].data[row_offset + col] = rc_matrix[mA].data[row_offset + col] - rc_matrix[mB].data[row_offset + col]; + } + } + + return true; +} + +// Swaps contents of Matrix A() with Matrix B() +void SwapMatrix(uint32_t mA, uint32_t mB, int process_num) +{ + int tmp_mat1 = process_num < 0 ? RC_TMP_MATRIX : (process_num*2) + RC_PROCESS_TMP_MATRIX_OFFSET; + //int tmp_mat2 = process_num < 0 ? RC_TMP_MATRIX : (process_num*2) + RC_PROCESS_TMP_MATRIX_OFFSET + 1; + + DimMatrix(tmp_mat1, rc_matrix[mA].r, rc_matrix[mA].c); + CopyMatrix(mB, tmp_mat1); + CopyMatrix(mA, mB); + CopyMatrix(tmp_mat1, mA); + DimMatrix(tmp_mat1, 1, 1); +} + +// Swaps columns C1% and C2% in matrix A() +bool SwapMatrixColumn(uint32_t mA, uint32_t C1, uint32_t C2) +{ + if(C1 >= rc_matrix[mA].c || C2 >= rc_matrix[mA].c) + { + std::cout << "SwapMatrixColumn Error: C1 or C2 refers to column outside of A" << std::endl; + return false; + } + + double tmp = 0; + + uint32_t row_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + tmp = rc_matrix[mA].data[row_offset + C1]; + rc_matrix[mA].data[row_offset + C1] = rc_matrix[mA].data[row_offset + C2]; + rc_matrix[mA].data[row_offset + C2] = tmp; + } + + return true; +} + +// Swaps rows R1% and R2% in matrix A() +bool SwapMatrixRow(uint32_t mA, uint32_t R1, uint32_t R2) +{ + if(R1 >= rc_matrix[mA].r || R2 >= rc_matrix[mA].r) + { + std::cout << "SwapMatrixRow Error: R1 or R2 refers to row outside of A" << std::endl; + return false; + } + + double tmp = 0; + uint32_t r1_offset = R1 * rc_matrix[mA].c; + uint32_t r2_offset = R2 * rc_matrix[mA].c; + + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + tmp = rc_matrix[mA].data[r1_offset + col]; + rc_matrix[mA].data[r1_offset + col] = rc_matrix[mA].data[r2_offset + col]; + rc_matrix[mA].data[r2_offset + col] = tmp; + } + + return true; +} + +// Transposes matrix A(), output matrix B() +bool TransposeMatrix(uint32_t mA, uint32_t mB) +{ + DimMatrix(mB, rc_matrix[mA].c, rc_matrix[mA].r); + + uint32_t row_offset = 0; + uint32_t trans_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mA].r; row++) + { + row_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mA].c; col++) + { + trans_offset = col * rc_matrix[mB].c; + rc_matrix[mB].data[trans_offset + row] = rc_matrix[mA].data[row_offset + col]; + } + } + return true; +} + + +// Splits matrix A() into square Coefficient B() and remaining Augment C() +bool UnAugmentMatrix(uint32_t mA, uint32_t mB, uint32_t mC) +{ + if(rc_matrix[mA].c <= rc_matrix[mA].r) + { + std::cout << "UnAugmentMatrix Error: matrix A must have more columns than rows" << std::endl; + return false; + } + + //Br% = Ar%: + //Bc% = Ar%: + DimMatrix(mB, rc_matrix[mA].r, rc_matrix[mA].r); + + //Cr% = Ar%: + //Cc% = Ac% - Bc%: + DimMatrix(mC, rc_matrix[mA].r, rc_matrix[mA].c - rc_matrix[mB].c); + + uint32_t row_offset = 0; + uint32_t a_offset = 0; + for(uint32_t row = 0; row < rc_matrix[mB].r; row++) + { + row_offset = row*rc_matrix[mB].c; + a_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mB].c; col++) + { + rc_matrix[mB].data[row_offset + col] = rc_matrix[mA].data[a_offset + col]; + } + } + + for(uint32_t row = 0; row < rc_matrix[mC].r; row++) + { + row_offset = row*rc_matrix[mC].c; + a_offset = row * rc_matrix[mA].c; + for(uint32_t col = 0; col < rc_matrix[mC].c; col++) + { + rc_matrix[mC].data[row_offset + col] = rc_matrix[mA].data[a_offset + (col + rc_matrix[mB].c)]; + } + } + + return true; +} + + +// Clears contents of matrix A(). +void ZeroMatrix (uint32_t mA) +{ + ClearMatrix(mA); +} + +void GetMatrixSize(uint32_t mA, double* r, double* c) +{ + *r = rc_matrix[mA].r; + *c = rc_matrix[mA].c; +} + +void IncrementMatrixRows(uint32_t mA, uint32_t mB, uint32_t r, uint32_t num_rows, double value) +{ + if(num_rows < 0) + return; + + if( r >= rc_matrix[mA].r ) + r = rc_matrix[mA].r -1; + + if( (r+num_rows) >= rc_matrix[mA].r ) + num_rows = rc_matrix[mA].r - r; + + CopyMatrix(mA, mB); + + for(int mr = r; mr < (r+num_rows); mr++) + { + for(int mc = 0; mc < rc_matrix[mA].c; mc++) + { + double mv = MatrixValue(mA, mr, mc) + value; + SetMatrixValue(mB, mr, mc, mv); + } + } +} + +void IncrementMatrixColumns(uint32_t mA, uint32_t mB, uint32_t c, uint32_t num_cols, double value) +{ + if(num_cols < 0) + return; + + if( c >= rc_matrix[mA].c ) + c = rc_matrix[mA].c -1; + + if( (c+num_cols) >= rc_matrix[mA].c ) + num_cols = rc_matrix[mA].c - c; + + CopyMatrix(mA, mB); + + for(int mr = 0; mr < rc_matrix[mA].r; mr++) + { + for(int mc = c; mc < (c+num_cols); mc++) + { + double mv = MatrixValue(mA, mr, mc) + value; + SetMatrixValue(mB, mr, mc, mv); + } + } +} + +void JoinMatrixRows(uint32_t mA, uint32_t mB, uint32_t mC) +{ + if(rc_matrix[mA].r != rc_matrix[mB].r) + return; + + uint32_t num_cols = rc_matrix[mA].c + rc_matrix[mB].c; + uint32_t num_rows = rc_matrix[mA].r; + + DimMatrix(mC, num_rows, num_cols, false); + + for(int c = 0; c < rc_matrix[mA].c; c++) + { + for(int r = 0; r < num_rows; r++) + { + double mv = MatrixValue(mA, r, c); + SetMatrixValue(mC, r, c, mv); + } + } + + for(int c = 0; c < rc_matrix[mB].c; c++) + { + for(int r = 0; r < num_rows; r++) + { + double mv = MatrixValue(mB, r, c); + SetMatrixValue(mC, r, rc_matrix[mA].c + c, mv); + } + } +} + +void JoinMatrixColumns(uint32_t mA, uint32_t mB, uint32_t mC) +{ + if(rc_matrix[mA].c != rc_matrix[mB].c) + return; + + uint32_t num_cols = rc_matrix[mA].c; + uint32_t num_rows = rc_matrix[mA].r + rc_matrix[mB].r; + + DimMatrix(mC, num_rows, num_cols, false); + + for(int c = 0; c < num_cols; c++) + { + for(int r = 0; r < rc_matrix[mA].r; r++) + { + double mv = MatrixValue(mA, r, c); + SetMatrixValue(mC, r, c, mv); + } + } + + for(int c = 0; c < num_cols; c++) + { + for(int r = 0; r < rc_matrix[mB].r; r++) + { + double mv = MatrixValue(mB, r, c); + SetMatrixValue(mC, rc_matrix[mA].r + r, c, mv); + } + } +} + +#endif // RC_MATRIX_H_INCLUDED diff --git a/rcbasic_runtime/rc_media.h b/rcbasic_runtime/rc_media.h new file mode 100644 index 0000000..6016070 --- /dev/null +++ b/rcbasic_runtime/rc_media.h @@ -0,0 +1,6502 @@ +#include "rc_os_defines.h" + +#ifdef RC_ANDROID +#define RC_MOBILE +#endif + +#ifdef RC_IOS +#define RC_MOBILE +#endif + + +#ifdef RC_ANDROID + +#include +//Using SDL and standard IO +#include "SDL.h" +#include "SDL_image.h" +#include "SDL2_gfxPrimitives.h" +#include "SDL_ttf.h" +#include +#include +#include +#include "SDL_mixer.h" +#include "SDL_net.h" +//#include "../SDL/src/core/android/SDL_android.h" + +//#include "../SDL/src/dynapi/SDL_dynapi_overrides.h" + +//#include "../soft_render/SDL_rotate.c" + +#include + +#include "theoraplay.h" + +#else + +#ifdef RC_IOS + +//Using SDL and standard IO +#include "SDL2/SDL.h" +#include "SDL2/SDL_image.h" +#include "SDL2/SDL2_gfxPrimitives.h" +#include "SDL2/SDL_ttf.h" +#include +#include +#include +#include "SDL2/SDL_mixer.h" +#include "SDL2/SDL_net.h" + +#include + +#include "theoraplay.h" + +#else +//Using SDL and standard IO +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "theoraplay.h" + +#endif //RC_IOS + +#endif // RC_ANDROID + +//#include "soft_render/SDL_rotate.c" + +#include + +using namespace std; + +#ifdef RC_MOBILE +//Screen dimension constants +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; + +const int MAX_WINDOWS = 1; //8 +const int MAX_SCREENS = 8; //32 +const int MAX_IMAGES = 4096; //65536; +const int MAX_SPRITES = 32; //1024; +const int MAX_SOUNDS = 1024; +const int MAX_MUSIC = 1; +const int MAX_FONTS = 32; +const int MAX_FINGERS = 10; +const int MAX_SOCKETS = 256; +const int MAX_ACCELS = 20; +const int MAX_GYROS = 20; +const int MAX_JOYSTICKS = 8; +#else + +//Screen dimension constants +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; + +const int MAX_WINDOWS = 8; //8 +const int MAX_SCREENS = 8; //32 +const int MAX_IMAGES = 4096; //65536; +const int MAX_SOUNDS = 1024; +const int MAX_MUSIC = 1; +const int MAX_FONTS = 32; +const int MAX_FINGERS = 10; +const int MAX_SOCKETS = 256; +const int MAX_ACCELS = 20; +const int MAX_GYROS = 20; +const int MAX_JOYSTICKS = 8; +#endif // RC_MOBILE + +SDL_Window * rc_win[MAX_WINDOWS]; +int rc_win_event[MAX_WINDOWS]; +SDL_Texture * rc_backBuffer[MAX_WINDOWS]; +SDL_Rect rc_bb_rect[MAX_WINDOWS]; +SDL_Surface * rc_win_surface[MAX_WINDOWS]; +SDL_Renderer * rc_win_renderer[MAX_WINDOWS]; +Uint32 rc_win_id[MAX_WINDOWS]; +bool rc_win_exitOnClose[MAX_WINDOWS]; + +Uint32 rc_screen_format[MAX_WINDOWS]; + +SDL_Texture * rc_himage[MAX_IMAGES][MAX_WINDOWS]; +SDL_Rect rc_himage_rect[MAX_IMAGES]; +bool rc_image_isLoaded[MAX_IMAGES]; + +SDL_Texture * rc_hscreen[MAX_WINDOWS][MAX_SCREENS]; +SDL_Surface * rc_sscreen[MAX_WINDOWS][MAX_SCREENS]; +SDL_Rect rc_screen_rect[MAX_WINDOWS][MAX_SCREENS]; +int rc_screen_z[MAX_WINDOWS][MAX_SCREENS]; +SDL_Rect rc_screenview[MAX_WINDOWS][MAX_SCREENS]; +int rc_screen_width[MAX_WINDOWS][MAX_SCREENS]; +int rc_screen_height[MAX_WINDOWS][MAX_SCREENS]; +Uint8 rc_screen_transparent[MAX_WINDOWS][MAX_SCREENS]; +int rc_screen_zOrder[MAX_WINDOWS][MAX_SCREENS]; +bool rc_screen_visible[MAX_WINDOWS][MAX_SCREENS]; + +SDL_Surface * rc_simage[MAX_IMAGES]; +SDL_Rect rc_image_rect[MAX_IMAGES]; +Uint32 rc_image_width[MAX_IMAGES]; +Uint32 rc_image_height[MAX_IMAGES]; +Uint32 rc_image_colorKey[MAX_IMAGES]; +Uint8 rc_image_colorKey_r[MAX_IMAGES]; +Uint8 rc_image_colorKey_g[MAX_IMAGES]; +Uint8 rc_image_colorKey_b[MAX_IMAGES]; +Uint8 rc_image_colorKey_a[MAX_IMAGES]; + +int rc_active_window = -1; +int rc_active_screen = -1; + +Uint32 rc_ink = 0x00000000; +SDL_Color rc_ink_color; +Uint32 rc_paper = 0x00000000; +Uint32 rc_clearColor = 0x00000000; +Uint32 rc_colorKey = 0x00000000; +SDL_Color rc_colorKey_color; +int rc_colorKey_switch = 0; + +int rc_console_width[MAX_WINDOWS]; //number of characters wide +int rc_console_height[MAX_WINDOWS]; //number of rows +int rc_sConsole_x[MAX_WINDOWS]; +int rc_sConsole_y[MAX_WINDOWS]; +Uint8 rc_cursor_visible = 1; +SDL_Color rc_console_pen; +int rc_pen_color = 0x00FFFFFF; +SDL_Surface * rc_console = NULL; +SDL_Texture * rc_hconsole[MAX_WINDOWS]; +TTF_Font * rc_console_font = NULL; +string rc_input_buffer = ""; + +TTF_Font * rc_draw_font[MAX_FONTS]; +string rc_draw_font_path = ""; +int rc_active_font = -1; + +int rc_inkey = 0; +SDL_Keycode rc_keycode; +SDL_Scancode rc_scancode; +SDL_Keymod rc_keymod; +int rc_mouseX = 0; +int rc_mouseY = 0; +int rc_mbutton1 = 0; +int rc_mbutton2 = 0; +int rc_mbutton3 = 0; +int rc_mwheelx = 0; +int rc_mwheely = 0; + +int rc_global_mouseX = 0; +int rc_global_mouseY = 0; + +//SDL_Event event; + +Uint32 prev_color = 0; + +bool rc_engine_isRunning = false; +bool rc_engine_isInitialized = false; +bool rc_media_isActive = false; + +const Uint8 * keyState = NULL; + +SDL_Joystick * rc_joystick[MAX_JOYSTICKS]; +int rc_joy_axis[MAX_JOYSTICKS][100]; +int rc_numJoysticks = 0; +int rc_joybutton[MAX_JOYSTICKS][100]; +SDL_JoystickID rc_joyID[MAX_JOYSTICKS]; + +SDL_Joystick * tmp_joy; +SDL_JoystickID tmp_joy_id; +int tmp_joy_flag = 0; + +SDL_Haptic * rc_haptic[MAX_JOYSTICKS]; //1 for each joystick + +double rc_pressure = 0; +int rc_touchX = 0; +int rc_touchY = 0; +int rc_motionX = 0; +int rc_motionY = 0; +int rc_touch = 0; +int rc_mt_status = 0; +int rc_mt_x = 0; +int rc_mt_y = 0; +int rc_mt_numFingers = 0; +double rc_mt_theta = 0; +double rc_mt_dist = 0; +SDL_TouchID rc_touchDevice; +SDL_Finger rc_finger[MAX_FINGERS]; +set rc_fingers_pressed; + +SDL_Sensor * rc_accel[MAX_ACCELS]; +int num_accels = 0; + +SDL_Sensor * rc_gyro[MAX_GYROS]; +int num_gyros = 0; + +int rc_win_width[MAX_WINDOWS]; +int rc_win_height[MAX_WINDOWS]; + +Uint32 rc_update_timer = 0; +Uint32 rc_auto_time = 0; +int rc_update_flag = 0; + +Mix_Chunk * rc_sound[MAX_SOUNDS]; +Mix_Music * rc_music; + +TCPsocket rc_socket[MAX_SOCKETS]; + +UDPsocket rc_udp_socket[MAX_SOCKETS]; +UDPpacket * rc_udp_packet; +int rc_udp_channel; +string rc_udp_data; +int rc_udp_len; +int rc_udp_maxlen; +string rc_udp_host; +Uint16 rc_udp_port; +int rc_packet_size = 0; +SDLNet_SocketSet rc_socket_set; + + +SDL_PixelFormat * rc_pformat; +SDL_DisplayMode rc_displayMode[MAX_WINDOWS]; + +string rc_textinput_string = ""; +//string * rc_textinput_oldString; +string rc_textinput_char = ""; +int rc_textinput_timer = 0; +int rc_textinput_delay = 100; +bool rc_textinput_flag = true; +bool rc_textinput_isActive = false; +int rc_textinput_waitHold = 800; +bool rc_textinput_hold = false; +bool rc_toggleBackspace = true; + + +static Uint32 baseticks = 0; + +uint32_t rc_fps[MAX_WINDOWS]; +uint32_t rc_fps_frames[MAX_WINDOWS]; +uint32_t rc_fps_timer[MAX_WINDOWS]; + +#ifdef RC_MOBILE +double rc_mouse_scale_x = 0; +double rc_mouse_scale_y = 0; +#else +double rc_fullscreen_mouse_scale_x[MAX_WINDOWS]; +double rc_fullscreen_mouse_scale_y[MAX_WINDOWS]; +#endif // RC_MOBILE + +typedef struct AudioQueue +{ + const THEORAPLAY_AudioPacket *audio; + int offset; + struct AudioQueue *next; +} AudioQueue; + +static volatile AudioQueue *audio_queue = NULL; +static volatile AudioQueue *audio_queue_tail = NULL; + +THEORAPLAY_Decoder *decoder = NULL; +const THEORAPLAY_VideoFrame *video = NULL; +const THEORAPLAY_AudioPacket *audio = NULL; +SDL_Texture * overlay = NULL; +void * overlay_pixels; +int pitch; +SDL_Event event; +Uint32 framems = 0; +int initfailed = 0; +int quit = 0; +bool rc_video_isPlaying = false; +Uint32 rc_video_position = 0; +bool rc_video_reset = false; +int rc_video_loops = 0; +const THEORAPLAY_AudioPacket * first_audio = NULL; +const THEORAPLAY_VideoFrame * first_video = NULL; +bool rc_audio_isOpen = false; +bool rc_video_isLoaded = false; +string rc_video_file = ""; +bool rc_video_isPaused = false; +Uint32 rc_video_pauseTicks = 0; +bool rc_video_end = false; +SDL_Rect rc_video_dstrect; +int rc_video_width = 0; +int rc_video_height = 0; +int rc_video_length = 0; +int rc_video_fps = 0; +int rc_video_currentLoop = 0; + +bool mobile_active_window_flag = true; + +void rc_setTouchFingerEvent(SDL_FingerID fingerID, double x, double y, double pressure) +{ + for(int i = 0; i < MAX_FINGERS; i++) + { + if(rc_finger[i].id == -1 || rc_finger[i].id == fingerID) + { + rc_finger[i].id = fingerID; + rc_finger[i].x = x; + rc_finger[i].y = y; + rc_finger[i].pressure = pressure; + if(rc_finger[i].pressure > 0) + { + rc_fingers_pressed.insert(i); + } + return; + } + } +} + +int mobile_event_filter(void* userdata, SDL_Event* evt) +{ + SDL_Event event = evt[0]; + switch(evt->type) + { + case SDL_APP_WILLENTERBACKGROUND: + mobile_active_window_flag = false; + break; + case SDL_APP_DIDENTERFOREGROUND: + if(!mobile_active_window_flag) + { + //rc_win_renderer[0] = SDL_GetRenderer(rc_win[0]); + } + mobile_active_window_flag = true; + break; + + case SDL_FINGERDOWN: + rc_touch = 1; + rc_touchX = event.tfinger.x * rc_win_width[rc_active_window]; + rc_touchY = event.tfinger.y * rc_win_height[rc_active_window]; +#ifdef RC_IOS + rc_pressure = 1; //FIXME: On IOS pressure is always getting reported as 0 on finger down so I am just setting it to 1 until I figure this out +#else + rc_pressure = event.tfinger.pressure; +#endif + rc_setTouchFingerEvent(event.tfinger.fingerId, rc_touchX, rc_touchY, rc_pressure); + break; + case SDL_FINGERUP: + rc_touch = 0; + rc_mt_status = 0; + rc_touchX = event.tfinger.x * rc_win_width[rc_active_window]; + rc_touchY = event.tfinger.y * rc_win_height[rc_active_window]; + rc_pressure = event.tfinger.pressure; + rc_setTouchFingerEvent(event.tfinger.fingerId, -1, -1, 0); + break; + case SDL_FINGERMOTION: + rc_touch = 1; + rc_touchX = event.tfinger.x * rc_win_width[rc_active_window]; + rc_touchY = event.tfinger.y * rc_win_height[rc_active_window]; + rc_motionX = event.tfinger.dx * rc_win_width[rc_active_window]; + rc_motionY = event.tfinger.dy * rc_win_height[rc_active_window]; +#ifdef RC_IOS + rc_pressure = 1; +#else + rc_pressure = event.tfinger.pressure; +#endif + rc_setTouchFingerEvent(event.tfinger.fingerId, rc_touchX, rc_touchY, rc_pressure); + break; + case SDL_MULTIGESTURE: + rc_touch = 2; + rc_mt_status = 1; + rc_mt_x = event.mgesture.x; + rc_mt_y = event.mgesture.y; + rc_mt_numFingers = event.mgesture.numFingers; + rc_mt_dist = event.mgesture.dDist; + rc_mt_theta = event.mgesture.dTheta; +#ifdef RC_IOS + rc_pressure = 1; +#else + rc_pressure = event.tfinger.pressure; +#endif + break; + + } + return 0; +} + +bool rc_media_init() +{ + rc_socket_set = SDLNet_AllocSocketSet(MAX_SOCKETS*2); //*2 for udp and tcp + + if(rc_socket_set == NULL) + { + cout << "Init Error: " << SDL_GetError() << endl; + } + + for(int i = 0; i < MAX_SOCKETS; i++) + { + rc_socket[i] = NULL; + rc_udp_socket[i] = NULL; + } + + for(int i = 0; i < MAX_FONTS; i++) + rc_draw_font[i] = NULL; + + for(int i = 0; i < MAX_SOUNDS; i++) + rc_sound[i] = NULL; + + rc_music = NULL; + + for(int i = 0; i < MAX_WINDOWS; i++) + { + rc_win[i] = NULL; + rc_win_surface[i] = NULL; + rc_win_renderer[i] = NULL; + rc_win_id[i] = 0; + rc_hconsole[i] = NULL; + rc_backBuffer[i] = NULL; + rc_bb_rect[i].x = 0; + rc_bb_rect[i].y = 0; + rc_bb_rect[i].w = 0; + rc_bb_rect[i].h = 0; + + rc_fps[i] = 0; + rc_fps_frames[i] = 0; + rc_fps_timer[i] = 0; + + for(int j = 0; j < MAX_SCREENS; j++) + { + rc_hscreen[i][j] = NULL; + rc_sscreen[i][j] = NULL; + rc_screen_rect[i][j].x = 0; + rc_screen_rect[i][j].y = 0; + rc_screen_rect[i][j].w = 0; + rc_screen_rect[i][j].h = 0; + rc_screen_z[i][j] = j; + rc_screen_zOrder[i][j] = j; + rc_screen_visible[i][j] = false; + } + } + for(int i = 0; i < MAX_IMAGES; i++) + { + for(int w = 0; w < MAX_WINDOWS; w++) + rc_himage[i][w] = NULL; + + rc_simage[i] = NULL; + rc_image_rect[i].x = 0; + rc_image_rect[i].y = 0; + rc_image_rect[i].w = 0; + rc_image_rect[i].h = 0; + rc_image_isLoaded[i] = false; + } + rc_ink_color.r = 0; + rc_ink_color.g = 0; + rc_ink_color.b = 0; + rc_ink_color.a = 0; + #ifdef RC_WEB + if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) + #else + if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_EVENTS | SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_SENSOR) < 0) + #endif + { + cout << "Init Error: " << SDL_GetError() << endl; + //return false; + } + + #ifdef RC_MOBILE + SDL_SetEventFilter(mobile_event_filter, NULL); + #endif // RC_MOBILE + + if(IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF) < 0) + { + cout << "IMG Init Error: " << IMG_GetError() << endl; + //return false; + } + + if(TTF_Init() < 0) + { + cout << "TTF Init Error: " << TTF_GetError() << endl; + //return false; + } + + if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 2048) < 0) + { + cout << "OpenAudio Error: " << Mix_GetError() << endl; + } + + if (SDLNet_Init() < 0) + { + fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); + exit(EXIT_FAILURE); + } + + for(int i = 0; i < MAX_FINGERS; i++) + { + rc_finger[i].id = -1; + rc_finger[i].x = -1; + rc_finger[i].y = -1; + rc_finger[i].pressure = 0; + } + + for(int i = 0; i < SDL_NumSensors(); i++) + { + rc_accel[num_accels] = NULL; + rc_gyro[num_gyros] = NULL; + switch(SDL_SensorGetDeviceType(i)) + { + case SDL_SENSOR_ACCEL: + rc_accel[num_accels] = SDL_SensorOpen(i); + num_accels++; + break; + case SDL_SENSOR_GYRO: + rc_gyro[num_gyros] = SDL_SensorOpen(i); + num_gyros++; + break; + } + } + + rc_pformat = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888); + + //rc_active_font = -1; + + rc_udp_packet = SDLNet_AllocPacket(512); + rc_packet_size = 512; + + rc_console_pen.r = 255; + rc_console_pen.g = 255; + rc_console_pen.b = 255; + rc_console_pen.a = 0; + rc_media_isActive = true; + + for(int i = 0; i < MAX_JOYSTICKS; i++) + { + if(i < SDL_NumJoysticks()) + { + rc_joystick[i] = SDL_JoystickOpen(i); + if(rc_joystick[i]==NULL) + { + cout << "Joystick " << i << " could not be opened: " << SDL_GetError() << endl; + } + rc_joyID[i] = SDL_JoystickInstanceID(rc_joystick[i]); + #ifdef RC_WEB + rc_haptic[i] = NULL; + #else + rc_haptic[i] = SDL_HapticOpenFromJoystick(rc_joystick[i]); + SDL_HapticRumbleInit(rc_haptic[i]); + #endif + //if(rc_haptic[i] == NULL){ cout << "HAP NULL: " << SDL_GetError() << endl; } + rc_numJoysticks++; + } + else + { + rc_joystick[i] = NULL; + rc_haptic[i] = NULL; + rc_joyID[i] = -1; + } + } + SDL_SetHint("SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", "1"); + + return true; +} + +void rc_media_quit() +{ + for(int i = 0; i < MAX_FONTS; i++) + { + if(rc_draw_font[i] != NULL) + TTF_CloseFont(rc_draw_font[i]); + } + + //cout << "Font closed" << endl; + + for(int i = 0; i < MAX_SOUNDS; i++) + { + if(rc_sound[i] != NULL) + Mix_FreeChunk(rc_sound[i]); + rc_sound[i] = NULL; + } + if(rc_music != NULL) + Mix_FreeMusic(rc_music); + rc_music = NULL; + + for(int i = 0; i < MAX_JOYSTICKS; i++) + { + SDL_JoystickClose(rc_joystick[i]); + SDL_HapticClose(rc_haptic[i]); + } + + //cout << "Music Closed" << endl; + + for(int i = 0; i < MAX_WINDOWS; i++) + { + + //cout << "Destroy Canvases" << endl; + + for(int j = 0; j < MAX_SCREENS; j++) + { + if(rc_sscreen[i][j] != NULL) + { + //cout << "Free Surface rc_sscreen[" << i << "][" << j << "] ----- "; + SDL_FreeSurface(rc_sscreen[i][j]); + //cout << "SUCCESS\n"; + //SDL_DestroyTexture(rc_hscreen[i][j]); + } + if(rc_hscreen[i][j] != NULL) + { + SDL_DestroyTexture(rc_hscreen[i][j]); + } + } + + //cout << "Destroy Images" << endl; + + for(int j = 0; j < MAX_IMAGES; j++) + { + if(rc_himage[j][i] != NULL) + SDL_DestroyTexture(rc_himage[j][i]); + rc_himage[j][i] = NULL; + } + + //cout << "Destroy Window #" << i << endl; + + if(rc_win[i] != NULL) + { + SDL_DestroyRenderer(rc_win_renderer[i]); + rc_win_renderer[i] = NULL; + SDL_DestroyWindow(rc_win[i]); + rc_win[i] = NULL; + } + } + + //cout << "NORMAL BOOTS" << endl; + + if(audio) + { + THEORAPLAY_freeAudio(audio); + audio = NULL; + } + if(video) + { + THEORAPLAY_freeVideo(video); + video = NULL; + } + if(decoder) + { + THEORAPLAY_stopDecode(decoder); + decoder = NULL; + } + IMG_Quit(); + TTF_Quit(); + Mix_Quit(); + if(rc_socket_set) + { + SDLNet_FreeSocketSet(rc_socket_set); + rc_socket_set = NULL; + } + //SDLNet_FreePacket(rc_udp_packet); + SDLNet_Quit(); + SDL_Quit(); +} + +int rc_debug_msg(string msg) +{ + const SDL_MessageBoxButtonData buttons[] = { + { /* .flags, .buttonid, .text */ 0, 0, "no" }, + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "yes" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "cancel" }, + }; + const SDL_MessageBoxColorScheme colorScheme = { + { /* .colors (.r, .g, .b) */ + /* [SDL_MESSAGEBOX_COLOR_BACKGROUND] */ + { 255, 0, 0 }, + /* [SDL_MESSAGEBOX_COLOR_TEXT] */ + { 0, 255, 0 }, + /* [SDL_MESSAGEBOX_COLOR_BUTTON_BORDER] */ + { 255, 255, 0 }, + /* [SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND] */ + { 0, 0, 255 }, + /* [SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] */ + { 255, 0, 255 } + } + }; + const SDL_MessageBoxData messageboxdata = { + SDL_MESSAGEBOX_INFORMATION, /* .flags */ + NULL, /* .window */ + msg.c_str(), /* .title */ + "select a button", /* .message */ + SDL_arraysize(buttons), /* .numbuttons */ + buttons, /* .buttons */ + &colorScheme /* .colorScheme */ + }; + int buttonid; + if (SDL_ShowMessageBox(&messageboxdata, &buttonid) < 0) { + SDL_Log("error displaying message box"); + return 1; + } + if (buttonid == -1) { + SDL_Log("no selection"); + } else { + SDL_Log("selection was %s", buttons[buttonid].text); + } + return 0; +} + +inline Uint32 rc_media_windowMode(int visible_flag, int fullscreen_flag, int resizable_flag, int borderless_flag, int highDPI_flag) +{ + Uint32 window_mode = ( visible_flag == 0 ? SDL_WINDOW_HIDDEN : SDL_WINDOW_SHOWN ) | + ( fullscreen_flag == 0 ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP ) | + ( resizable_flag == 0 ? 0 : SDL_WINDOW_RESIZABLE ) | + ( borderless_flag == 0 ? 0 : SDL_WINDOW_BORDERLESS ) | + ( highDPI_flag == 0 ? 0 : SDL_WINDOW_ALLOW_HIGHDPI ); + return window_mode; +} + +inline Uint32 rc_media_windowFlags(int win_num) +{ + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window #" << win_num << " is not an available Window Slot" << endl; + return 0; + } + if(rc_win[win_num] == NULL) + { + cout << "Window #" << win_num << " is not currently open" << endl; + return 0; + } + return SDL_GetWindowFlags(rc_win[win_num]); +} + +inline bool rc_media_openWindow_hw(int win_num, string caption, int x, int y, int w, int h, Uint32 flags, int vsync_flag) +{ + //cout << "start windowOpen" << endl; + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window #" << win_num << " is not an available Window Slot" << endl; + return false; + } + if(rc_win[win_num] != NULL) + { + cout << "Window #" << win_num << " is currently open" << endl; + return false; + } + + bool vsync = vsync_flag == 0 ? false : true; + rc_win_exitOnClose[win_num] = true; + + #ifdef RC_MOBILE + flags = flags | SDL_WINDOW_FULLSCREEN_DESKTOP; + #endif // RC_MOBILE + + rc_win[win_num] = SDL_CreateWindow(caption.c_str(), x, y, w, h, flags); + if(rc_win[win_num] == NULL) + { + cout << "Error: " << SDL_GetError() << endl; + return false; + } + + if(rc_active_window == -1) + rc_active_window = win_num; + + //rc_win_surface[win_num] = SDL_GetWindowSurface(rc_win[win_num]); + rc_win_id[win_num] = SDL_GetWindowID(rc_win[win_num]); + + rc_win_width[win_num] = w; + rc_win_height[win_num] = h; + //SDL_SetSurfaceRLE(rc_win_surface[win_num],1); + //rc_console = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); + //SDL_SetColorKey(rc_console, SDL_TRUE, rc_clearColor); + //cout << "boob physics" << endl; + +#ifdef RC_MOBILE + rc_win_renderer[win_num] = SDL_GetRenderer(rc_win[win_num]); + if(rc_win_renderer[win_num] != NULL) + { + SDL_DestroyRenderer(rc_win_renderer[win_num]); + } +#endif // RC_MOBILE + + if(vsync) + rc_win_renderer[win_num] = SDL_CreateRenderer(rc_win[win_num], -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC); + else + rc_win_renderer[win_num] = SDL_CreateRenderer(rc_win[win_num], -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + + + if(rc_win_renderer[win_num] == NULL) + { +#ifdef RC_ANDROID + //rc_debug_msg("No Renderer"); + __android_log_write(ANDROID_LOG_ERROR, "This is crazy: ", SDL_GetError()); + rc_win_renderer[win_num] = SDL_GetRenderer(rc_win[win_num]); + if(rc_win_renderer[win_num] == NULL) + { + __android_log_write(ANDROID_LOG_ERROR, "Renderer Error: ", SDL_GetError()); + exit(0); + } + SDL_DestroyRenderer(rc_win_renderer[win_num]); + rc_win_renderer[win_num] = NULL; + if(vsync) + rc_win_renderer[win_num] = SDL_CreateRenderer(rc_win[win_num], -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); + else + rc_win_renderer[win_num] = SDL_CreateRenderer(rc_win[win_num], -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + + if(rc_win_renderer[win_num] == NULL) + { + __android_log_write(ANDROID_LOG_ERROR, "Renderer Error2: ", SDL_GetError()); + exit(0); + } +#else + cout << "WindowOpen Error: " << SDL_GetError() << endl; + exit(0); +#endif + } + + SDL_SetRenderDrawBlendMode(rc_win_renderer[win_num], SDL_BLENDMODE_BLEND); + + //cout << "booty" << endl; + +#ifndef RC_MOBILE + + for(int i = 0; i < MAX_IMAGES; i++) + { + if(rc_image_isLoaded[i]) + { + for(int w = 0; w < MAX_WINDOWS; w++) + { + if(rc_win[w] != NULL && rc_himage[i][w]==NULL) + { + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[i], rc_image_height[i], 32, 0, 0, 0, 0); + //cout << "ColorKey = " << (Uint32)rc_image_colorKey_r[i] << ", "; + //cout << (Uint32)rc_image_colorKey_g[i] << ", "; + //cout << (Uint32)rc_image_colorKey_b[i] << ", "; + //cout << (Uint32)rc_image_colorKey_a[i] << endl; + SDL_FillRect(tmp_surf, NULL, rc_image_colorKey[i]); + SDL_SetRenderTarget(rc_win_renderer[w], NULL); + SDL_Rect t_rect; + t_rect.x = 0; + t_rect.y = 0; + t_rect.w = tmp_surf->w; + t_rect.h = tmp_surf->h; + Uint8 r, g, b, a; + SDL_GetRenderDrawColor(rc_win_renderer[w], &r, &g, &b, &a); + SDL_SetRenderDrawColor(rc_win_renderer[w], rc_image_colorKey_r[i], rc_image_colorKey_g[i], rc_image_colorKey_b[i], 255); + SDL_RenderFillRect(rc_win_renderer[w], NULL); + SDL_SetRenderDrawColor(rc_win_renderer[w], r, g, b, a); + SDL_RenderCopy(rc_win_renderer[w], rc_himage[i][w], NULL, &t_rect); + SDL_RenderReadPixels(rc_win_renderer[w],&t_rect,tmp_surf->format->format,tmp_surf->pixels,tmp_surf->pitch); + SDL_SetColorKey(tmp_surf, SDL_TRUE, rc_image_colorKey[i]); + rc_himage[i][w] = SDL_CreateTextureFromSurface(rc_win_renderer[w], tmp_surf); + SDL_FreeSurface(tmp_surf); + break; + } + } + } + } + +#endif // RC_MOBILE + + //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + //SDL_RenderSetLogicalSize(rc_win_renderer[win_num], w, h); + + //cout << "boobs" << endl; + + rc_backBuffer[win_num] = SDL_CreateTexture(rc_win_renderer[win_num], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, w, h); + //cout << "dbg 1" << endl; + +#ifdef RC_MOBILE + + if(SDL_GetDesktopDisplayMode(0, &rc_displayMode[win_num])<0) + { + cout << "Something happend: " << SDL_GetError() << endl; + } + +#else + + if(SDL_GetWindowDisplayMode(rc_win[win_num], &rc_displayMode[win_num])<0) + { + cout << "Something happend: " << SDL_GetError() << endl; + } + +#endif // RC_ANDROID + //cout << "dbg 2" << endl; + rc_bb_rect[win_num].x = 0; + rc_bb_rect[win_num].y = 0; + //cout << "dbg 3" << endl; + rc_bb_rect[win_num].w = rc_displayMode[win_num].w; + //cout << "dbg 4" << endl; + rc_bb_rect[win_num].h = rc_displayMode[win_num].h; + + //cout << "cunt" << endl; + +#ifdef RC_MOBILE + rc_mouse_scale_x = (double)((double)w / (double)rc_displayMode[win_num].w); + rc_mouse_scale_y = (double)((double)h / (double)rc_displayMode[win_num].h); +#else + if((flags&SDL_WINDOW_FULLSCREEN_DESKTOP)!=0) + { + //cout << "fullscreen" << endl; + //cout << "W = " << w << endl; + //cout << "D.W = " << rc_displayMode[win_num].w << endl; + rc_fullscreen_mouse_scale_x[win_num] = (double)((double)w / (double)rc_displayMode[win_num].w); + //cout << "fs = " << rc_fullscreen_mouse_scale_x[win_num] << endl; + rc_fullscreen_mouse_scale_y[win_num] = (double)((double)h / (double)rc_displayMode[win_num].h); + //cout << "display mode = " << rc_fullscreen_mouse_scale_x[win_num] << ", " << rc_fullscreen_mouse_scale_y[win_num] << endl; + } + else + { + rc_fullscreen_mouse_scale_x[win_num] = 1; + rc_fullscreen_mouse_scale_y[win_num] = 1; + } +#endif // RC_ANDROID + + //#ifndef RC_ANDROID + rc_hconsole[win_num] = SDL_CreateTexture(rc_win_renderer[win_num],rc_pformat->format,SDL_TEXTUREACCESS_TARGET,w,h); + SDL_SetTextureBlendMode(rc_hconsole[win_num], SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(rc_win_renderer[win_num], rc_hconsole[win_num]); + SDL_SetRenderDrawColor(rc_win_renderer[win_num], 0, 0, 0, 0); + SDL_RenderClear(rc_win_renderer[win_num]); + SDL_SetRenderTarget(rc_win_renderer[win_num], NULL); + //#endif // RC_ANDROID + + //cout << "wtf" << endl; + + rc_console_width[win_num] = w/8; + rc_console_height[win_num] = h/8; + rc_sConsole_x[win_num] = 0; + rc_sConsole_y[win_num] = 0; + + //cout << "cdi" << endl; + +#ifdef RC_MOBILE + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_backBuffer[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], 0, 0, 0, 255); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + rc_win_width[win_num] = w; + rc_win_height[win_num] = h; +#else + SDL_SetRenderDrawColor(rc_win_renderer[win_num], 0, 0, 0, 255); + SDL_RenderClear(rc_win_renderer[win_num]); +#endif // RC_ANDROID + + SDL_RenderPresent(rc_win_renderer[win_num]); + + //cout << "open complete" << endl; + + //rc_debug_msg("Window Creation Successful"); + + return true; +} + +inline void rc_media_closeWindow_hw(int win_num) +{ + if(win_num < 0 && win_num >= MAX_WINDOWS) + { + cout << "Window Index is out of Range" << endl; + return; + } + SDL_DestroyTexture(rc_hconsole[win_num]); + SDL_DestroyTexture(rc_backBuffer[win_num]); + SDL_DestroyRenderer(rc_win_renderer[win_num]); + if(rc_win[win_num]!=NULL) + SDL_DestroyWindow(rc_win[win_num]); + rc_win_renderer[win_num] = NULL; + rc_win[win_num] = NULL; +} + +inline int rc_media_setRenderScaleQuality(int n) +{ + stringstream s; + s << n; + + if(SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, s.str().c_str())) + return 1; + return 0; +} + +inline int rc_media_getRenderScaleQuality() +{ + string hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY) == NULL ? "" : SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); + int hint_val = 0; + if(hint.compare("")!=0) + { + #ifdef RC_WINDOWS + hint_val = atoi(hint.c_str()); + #else + #ifdef RC_ANDROID + hint_val = atoi(hint.c_str()); + #else + hint_val = stoi(hint); + #endif + #endif + } + return hint_val; +} + +inline void rc_media_getDesktopDisplayMode(int index, double * w, double * h, double * freq) +{ + SDL_DisplayMode dm; + SDL_GetDesktopDisplayMode(index, &dm); + *w = (double)dm.w; + *h = (double)dm.h; + *freq = (double)dm.refresh_rate; +} + +inline void rc_media_setActiveWindow(int win_num) +{ + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window Index Out of Range" << endl; + return; + } + rc_active_window = win_num; +} + +void rc_media_raiseWindow(int win_num) +{ + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window Index Out of Range" << endl; + return; + } + if(rc_win[win_num]==NULL) + { + //cout << "Window does not Exist" << endl; + return; + } + rc_active_window = win_num; + SDL_RaiseWindow(rc_win[win_num]); +} + +void rc_media_showWindow(int win_num) +{ + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window Index Out of Range" << endl; + return; + } + if(rc_win[win_num]==NULL) + { + //cout << "Window does not Exist" << endl; + return; + } + SDL_ShowWindow(rc_win[win_num]); +} + +void rc_media_hideWindow(int win_num) +{ + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window Index Out of Range" << endl; + return; + } + if(rc_win[win_num]==NULL) + { + //cout << "Window does not Exist" << endl; + return; + } + SDL_HideWindow(rc_win[win_num]); +} + +bool rc_winCheck(int win_num) +{ + if(win_num < 0 || win_num >= MAX_WINDOWS) + { + cout << "Window Index Out of Range" << endl; + return false; + } + if(rc_win[win_num]==NULL) + { + //cout << "Window does not Exist" << endl; + return false; + } + return true; +} + +void rc_media_setWindowTitle(int win_num, string title) +{ + if(rc_winCheck(win_num)) + { + SDL_SetWindowTitle(rc_win[win_num], title.c_str()); + } + else + { + cout << "SetWindowTitle Error: Window #" << win_num << " is not an active window" << endl; + } +} + +string rc_media_getWindowTitle(int win_num) +{ + if(rc_winCheck(win_num)) + { + return SDL_GetWindowTitle(rc_win[win_num]); + } + else + { + cout << "WindowTitle Error: Window #" << win_num << " is not an active window" << endl; + return ""; + } +} + +void rc_media_setWindowPosition(int win_num, int x, int y) +{ + if(rc_winCheck(win_num)) + SDL_SetWindowPosition(rc_win[win_num], x, y); + else + cout << "SetWindowPosition Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_getWindowPosition(int win_num, double * x, double * y) +{ + int x_data=0, y_data=0; + if(rc_winCheck(win_num)) + SDL_GetWindowPosition(rc_win[win_num],&x_data,&y_data); + else + cout << "GetWindowPosition Error: Window #" << win_num << " is not an active window" << endl; + *x = x_data; + *y = y_data; +} + + +void rc_onResize(int win_num) +{ + SDL_Texture * current_tgt = SDL_GetRenderTarget(rc_win_renderer[win_num]); + int w = 0; + int h = 0; + SDL_DestroyTexture(rc_backBuffer[win_num]); + rc_backBuffer[win_num] = NULL; + Uint32 win_flags = SDL_GetWindowFlags(rc_win[win_num]); + if( (win_flags & SDL_WINDOW_RESIZABLE) && !(win_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) ) + SDL_GetWindowSize(rc_win[win_num], &w, &h); + else + { + w = rc_win_width[win_num]; + h = rc_win_height[win_num]; + } + rc_win_width[win_num] = w; + rc_win_height[win_num] = h; + //cout << "debug1: " << w << ", " << h << endl; + rc_backBuffer[win_num] = SDL_CreateTexture(rc_win_renderer[win_num], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, w, h); + +#ifdef RC_MOBILE + + if(SDL_GetDesktopDisplayMode(0, &rc_displayMode[win_num])<0) + { + cout << "Something happend: " << SDL_GetError() << endl; + } + +#else + + if(SDL_GetWindowDisplayMode(rc_win[win_num], &rc_displayMode[win_num])<0) + { + cout << "Something happend: " << SDL_GetError() << endl; + } + +#endif // RC_ANDROID + + rc_bb_rect[win_num].x = 0; + rc_bb_rect[win_num].y = 0; + rc_bb_rect[win_num].w = rc_displayMode[win_num].w; + rc_bb_rect[win_num].h = rc_displayMode[win_num].h; + + //cout << "bb_rect = " << rc_bb_rect[win_num].w << ", " << rc_bb_rect[win_num].h << endl; + + Uint32 flags = SDL_GetWindowFlags(rc_win[win_num]); + +#ifdef RC_MOBILE + rc_mouse_scale_x = (double)((double)w / (double)rc_displayMode[win_num].w); + rc_mouse_scale_y = (double)((double)h / (double)rc_displayMode[win_num].h); +#else + if((flags & SDL_WINDOW_FULLSCREEN_DESKTOP)!=0) + { + rc_fullscreen_mouse_scale_x[win_num] = (double)((double)rc_win_width[win_num] / (double)rc_displayMode[win_num].w); + rc_fullscreen_mouse_scale_y[win_num] = (double)((double)rc_win_height[win_num] / (double)rc_displayMode[win_num].h); + //cout << "resize_fullscreen: " << w << " / " << rc_displayMode[win_num].w << endl; + } + else + { + //cout << "resize window mode" << endl; + rc_fullscreen_mouse_scale_x[win_num] = 1; + rc_fullscreen_mouse_scale_y[win_num] = 1; + } +#endif // RC_ANDROID + + SDL_DestroyTexture(rc_hconsole[win_num]); + rc_hconsole[win_num] = SDL_CreateTexture(rc_win_renderer[win_num],rc_pformat->format,SDL_TEXTUREACCESS_TARGET,w,h); + SDL_SetTextureBlendMode(rc_hconsole[win_num], SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(rc_win_renderer[win_num], rc_hconsole[win_num]); + SDL_SetRenderDrawColor(rc_win_renderer[win_num], 0, 0, 0, 0); + SDL_RenderClear(rc_win_renderer[win_num]); + SDL_SetRenderTarget(rc_win_renderer[win_num], current_tgt); + + rc_console_width[win_num] = w/8; + rc_console_height[win_num] = h/8; + rc_sConsole_x[win_num] = 0; + rc_sConsole_y[win_num] = 0; + +} + + +void rc_media_setWindowSize(int win_num, int w, int h) +{ + if(rc_winCheck(win_num)) + { + SDL_SetWindowSize(rc_win[win_num], w, h); + + rc_win_width[win_num] = w; + rc_win_height[win_num] = h; + + rc_onResize(win_num); + } + else + cout << "SetWindowSize Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_getWindowSize(int win_num, double * w, double * h) +{ + int w_data = -1, h_data = -1; + if(rc_winCheck(win_num)) + SDL_GetWindowSize(rc_win[win_num], &w_data, &h_data); + else + cout << "GetWindowSize Error: Window#" << win_num << " is not an active window" << endl; + *w = w_data; + *h = h_data; +} + +void rc_media_setWindowMinSize(int win_num, int w, int h) +{ + if(rc_winCheck(win_num)) + SDL_SetWindowMinimumSize(rc_win[win_num], w, h); + else + cout << "SetWindowMinSize Error: Window#" << win_num << " is not an active window" << endl; +} + +void rc_media_getWindowMinSize(int win_num, double * w, double * h) +{ + int w_data=0, h_data=0; + if(rc_winCheck(win_num)) + SDL_GetWindowMinimumSize(rc_win[win_num], &w_data, &h_data); + else + cout << "GetWindowMinSize Error: Window #" << win_num << " is not an active window" << endl; + *w = w_data; + *h = h_data; +} + +void rc_media_setWindowMaxSize(int win_num, int w, int h) +{ + if(rc_winCheck(win_num)) + SDL_SetWindowMaximumSize(rc_win[win_num], w, h); + else + cout << "SetWindowMaxSize Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_getWindowMaxSize(int win_num, double * w, double * h) +{ + int w_data=0, h_data=0; + if(rc_winCheck(win_num)) + SDL_GetWindowMaximumSize(rc_win[win_num], &w_data, &h_data); + else + cout << "GetWindowMaxSize Error: Window #" << win_num << " is not an active window" << endl; + *w = w_data; + *h = h_data; +} + +bool rc_media_windowIsFullscreen(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + Uint32 wflags_cmp1 = wflags & SDL_WINDOW_FULLSCREEN; + Uint32 wflags_cmp2 = wflags & SDL_WINDOW_FULLSCREEN_DESKTOP; + if(wflags_cmp1 || wflags_cmp2) + { + //cout << "wflags = " << (int)wflags << endl; + //cout << "SDL_WIN_FSCREEN = " << (int)SDL_WINDOW_FULLSCREEN << endl; + //cout << "SDL_WIN_FSCREEN_D = " << (int)SDL_WINDOW_FULLSCREEN_DESKTOP << endl; + return true; + } + else + { + //cout << "wflags = " << (int)wflags << endl; + //cout << "SDL_WIN_FSCREEN = " << (int)SDL_WINDOW_FULLSCREEN << endl; + //cout << "SDL_WIN_FSCREEN_D = " << (int)SDL_WINDOW_FULLSCREEN_DESKTOP << endl; + return false; + } + } + else + { + cout << "WindowIsFullscreen Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowIsVisible(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_SHOWN) + return true; + else + return false; + } + else + { + cout << "WindowIsVisible Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowHasMouseFocus(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_MOUSE_FOCUS) + return true; + else + return false; + } + else + { + cout << "WindowHasMouseFocus Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowHasInputFocus(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_INPUT_FOCUS) + return true; + else + return false; + } + else + { + cout << "WindowHasInputFocus Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowIsBordered(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_BORDERLESS) + return false; + else + return true; + } + else + { + cout << "WindowIsBordered Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowIsResizable(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_RESIZABLE) + return true; + else + return false; + } + else + { + cout << "WindowIsResizable Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowIsMinimized(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_MINIMIZED) + return true; + else + return false; + } + else + { + cout << "WindowIsMinimized Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +bool rc_media_windowIsMaximized(int win_num) +{ + if(rc_winCheck(win_num)) + { + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + if(wflags & SDL_WINDOW_MAXIMIZED) + return true; + else + return false; + } + else + { + cout << "WindowIsMaximized Error: Window #" << win_num << " is not an active window" << endl; + return false; + } +} + +void rc_media_setWindowFullscreen(int win_num, int flag) +{ + if(rc_winCheck(win_num)) + { + switch(flag) + { + case 0: + flag = 0; + break; + default: + flag = SDL_WINDOW_FULLSCREEN_DESKTOP; + break; + } + + Uint32 wflags_preOp = SDL_GetWindowFlags(rc_win[win_num]); + if( flag != 0 && ( (wflags_preOp & SDL_WINDOW_FULLSCREEN_DESKTOP) || (wflags_preOp & SDL_WINDOW_FULLSCREEN) ) ) + return; + else if( flag == 0 && !((wflags_preOp & SDL_WINDOW_FULLSCREEN_DESKTOP) || (wflags_preOp & SDL_WINDOW_FULLSCREEN))) + return; + + if(SDL_SetWindowFullscreen(rc_win[win_num], flag) < 0) + { + cout << "SetWindowFullscreen Error: " << SDL_GetError() << endl; + return; + } + + rc_win_renderer[win_num] = SDL_GetRenderer(rc_win[win_num]); + //cout << "debug = " << (rc_win_renderer[win_num] == NULL) << endl; + + Uint32 wflags = SDL_GetWindowFlags(rc_win[win_num]); + Uint32 wflags_cmp1 = wflags & SDL_WINDOW_FULLSCREEN; + Uint32 wflags_cmp2 = wflags & SDL_WINDOW_FULLSCREEN_DESKTOP; + if(!(wflags_cmp1 || wflags_cmp2)) + { + #ifndef RC_MOBILE + rc_fullscreen_mouse_scale_x[win_num] = 1; + rc_fullscreen_mouse_scale_y[win_num] = 1; + #endif // RC_MOBILE + } + else if(SDL_GetWindowDisplayMode(rc_win[win_num], &rc_displayMode[win_num])<0) + { + cout << "Something happend: " << SDL_GetError() << endl; + #ifndef RC_MOBILE + rc_fullscreen_mouse_scale_x[win_num] = 1; + rc_fullscreen_mouse_scale_y[win_num] = 1; + #endif // RC_MOBILE + } + else + { + #ifndef RC_MOBILE + rc_fullscreen_mouse_scale_x[win_num] = (double)((double)rc_win_width[win_num] / (double)rc_displayMode[win_num].w); + rc_fullscreen_mouse_scale_y[win_num] = (double)((double)rc_win_height[win_num] / (double)rc_displayMode[win_num].h); + #endif // RC_MOBILE + } + + SDL_PumpEvents(); + SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); + // SDL_GetWindowDisplayMode(rc_win[win_num],&rc_displayMode[win_num]); + //rc_bb_rect[win_num].w = rc_displayMode[win_num].w; + //rc_bb_rect[win_num].h = rc_displayMode[win_num].h; + //rc_win_surface[win_num] = SDL_GetWindowSurface(rc_win[win_num]); + } + else + cout << "SetWindowFullscreen Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_maximizeWindow(int win_num) +{ + if(rc_winCheck(win_num)) + { + SDL_MaximizeWindow(rc_win[win_num]); + if( (SDL_GetWindowFlags(rc_win[win_num]) & SDL_WINDOW_RESIZABLE) ) + return; + SDL_GetWindowDisplayMode(rc_win[win_num],&rc_displayMode[win_num]); + rc_bb_rect[win_num].w = rc_displayMode[win_num].w; + rc_bb_rect[win_num].h = rc_displayMode[win_num].h; + rc_win_surface[win_num] = SDL_GetWindowSurface(rc_win[win_num]); + #ifndef RC_MOBILE + rc_fullscreen_mouse_scale_x[win_num] = (double)((double)rc_win_width[win_num] / (double)rc_displayMode[win_num].w); + rc_fullscreen_mouse_scale_y[win_num] = (double)((double)rc_win_height[win_num] / (double)rc_displayMode[win_num].h); + #endif // RC_MOBILE + } + else + cout << "MaximizeWindow Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_minimizeWindow(int win_num) +{ + if(rc_winCheck(win_num)) + { + SDL_MinimizeWindow(rc_win[win_num]); + SDL_GetWindowDisplayMode(rc_win[win_num],&rc_displayMode[win_num]); + rc_bb_rect[win_num].w = rc_displayMode[win_num].w; + rc_bb_rect[win_num].h = rc_displayMode[win_num].h; + rc_win_surface[win_num] = SDL_GetWindowSurface(rc_win[win_num]); + #ifndef RC_MOBILE + rc_fullscreen_mouse_scale_x[win_num] = (double)((double)rc_win_width[win_num] / (double)rc_displayMode[win_num].w); + rc_fullscreen_mouse_scale_y[win_num] = (double)((double)rc_win_height[win_num] / (double)rc_displayMode[win_num].h); + #endif // RC_MOBILE + } + else + cout << "MinimizeWindow Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_setWindowBordered(int win_num, bool b) +{ + SDL_bool bswitch = SDL_FALSE; + if(b) + bswitch = SDL_TRUE; + if(rc_winCheck(win_num)) + SDL_SetWindowBordered(rc_win[win_num], bswitch); + else + cout << "SetWindowBorder Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_setWindowResizable(int win_num, bool b) +{ + SDL_bool bswitch = SDL_FALSE; + if(b) + bswitch = SDL_TRUE; + if(rc_winCheck(win_num)) + SDL_SetWindowResizable(rc_win[win_num], bswitch); + else + cout << "SetWindowResizable Error: Window #" << win_num << " is not an active window" << endl; +} + +int rc_media_numWindows() +{ + int num = 0; + for(int i = 0; i < MAX_WINDOWS; i++) + if(rc_win[i]) + num++; + return num; +} + +bool rc_media_windowExists(int win_num) +{ + if(rc_winCheck(win_num)) + { + if(rc_win[win_num]) + return true; + return false; + } + return false; +} + +void rc_media_restoreWindow(int win_num) +{ + if(rc_winCheck(win_num)) + { + SDL_RestoreWindow(rc_win[win_num]); + SDL_GetWindowDisplayMode(rc_win[win_num], &rc_displayMode[win_num]); + rc_bb_rect[win_num].w = rc_displayMode[win_num].w; + rc_bb_rect[win_num].h = rc_displayMode[win_num].h; + rc_win_surface[win_num] = SDL_GetWindowSurface(rc_win[win_num]); + #ifndef RC_MOBILE + rc_fullscreen_mouse_scale_x[win_num] = (double)((double)rc_win_width[win_num] / (double)rc_displayMode[win_num].w); + rc_fullscreen_mouse_scale_y[win_num] = (double)((double)rc_win_height[win_num] / (double)rc_displayMode[win_num].h); + #endif // RC_MOBILE + } + else + cout << "RestoreWindow Error: Window #" << win_num << " is not an active window" << endl; +} + +void rc_media_setWindowIcon(int win_num, int slot) +{ + SDL_Rect img_rect; + img_rect.x = 0; + img_rect.y = 0; + img_rect.w = rc_image_width[slot]; + img_rect.h = rc_image_height[slot]; + if(rc_himage[slot][win_num] != NULL) + { + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + + SDL_SetColorKey(tmp_surf,SDL_TRUE,rc_image_colorKey[slot]); + + SDL_SetWindowIcon(rc_win[rc_active_window], tmp_surf); + + + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + SDL_DestroyTexture(tmp_tex); + SDL_FreeSurface(tmp_surf); + } +} + +string rc_media_getClipboardText() +{ + return (string) SDL_GetClipboardText(); +} + +void rc_media_setClipboardText(string txt) +{ + SDL_SetClipboardText(txt.c_str()); +} + +int rc_media_hasClipboardText() +{ + return (int)SDL_HasClipboardText(); +} + +bool rc_screenCheck(int s_num = -1) +{ + if(s_num == -1) + s_num = rc_active_screen; + if(s_num > MAX_SCREENS || s_num < 0) + return false; + if(rc_sscreen[rc_active_window][s_num] == NULL && rc_hscreen[rc_active_window][s_num] == NULL) + return false; + return true; +} + +void rc_media_openScreen_hw(int s_num, int w, int h, int vpx, int vpy, int vpw, int vph, int flag) +{ + //cout << "start CanvasOpen in " << rc_active_window << ", " << s_num << endl; + if(s_num < 0 || s_num > MAX_SCREENS) + { + cout << "Canvas #" << s_num << " is not available" << endl; + return; + } + if(rc_hscreen[rc_active_window][s_num]!=NULL) + { + cout << "Canvas #" << s_num << " is already open" << endl; + return; + } + //cout << "got to this point" << endl; + rc_hscreen[rc_active_window][s_num] = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, w, h); + //cout << "hscreen texture created" << endl; + rc_screen_transparent[rc_active_window][s_num] = 0; + + //cout << "Canvas is created" << endl; + + switch(flag) + { + case 0: + //solid screen + break; + case 1: + rc_screen_transparent[rc_active_window][s_num] = 1; + SDL_SetTextureBlendMode(rc_hscreen[rc_active_window][s_num], SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][s_num]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], 0, 0, 0, 0); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + //cout << "screen opened\n"; + break; + } + + //cout << "Flags are set" << endl; + + rc_screen_rect[rc_active_window][s_num].x = vpx; + rc_screen_rect[rc_active_window][s_num].y = vpy; + rc_screen_rect[rc_active_window][s_num].w = vpw; + rc_screen_rect[rc_active_window][s_num].h = vph; + rc_screen_width[rc_active_window][s_num] = w; + rc_screen_height[rc_active_window][s_num] = h; + rc_screenview[rc_active_window][s_num].x = 0; + rc_screenview[rc_active_window][s_num].y = 0; + rc_screenview[rc_active_window][s_num].w = vpw; + rc_screenview[rc_active_window][s_num].h = vph; + rc_screen_visible[rc_active_window][s_num] = true; + if(rc_active_screen == -1) + rc_active_screen = s_num; + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + //cout << "Canvas is open" << endl; +} + +void rc_media_closeScreen_hw(int s_num) +{ + if(rc_screenCheck(s_num)) + { + SDL_DestroyTexture(rc_hscreen[rc_active_window][s_num]); + rc_hscreen[rc_active_window][s_num] = NULL; + rc_screen_visible[rc_active_window][s_num] = false; + } +} + +void rc_media_screen_hw(int s_num) +{ + if(rc_screenCheck(s_num)) + { + rc_active_screen = s_num; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][s_num]); + //cout << "active screen = hscreen[" << rc_active_window << "][" << s_num << "]\n"; + } +} + +void rc_media_setScreenVisible(int s_num, int flag) +{ + if(rc_screenCheck(s_num) && flag == 0) + { + rc_screen_visible[rc_active_window][s_num] = false; + return; + } + rc_screen_visible[rc_active_window][s_num] = true; +} + +bool rc_media_screenIsVisible(int s_num) +{ + return rc_screen_visible[rc_active_window][s_num]; +} + +void rc_media_setScreenViewport(int s_num, int x, int y, int w, int h) +{ + if(rc_screenCheck(s_num)) + { + rc_screen_rect[rc_active_window][s_num].x = x; + rc_screen_rect[rc_active_window][s_num].y = y; + rc_screen_rect[rc_active_window][s_num].w = w; + rc_screen_rect[rc_active_window][s_num].h = h; + } +} + +void rc_media_getScreenViewport(int s_num, double * x, double * y, double * w, double * h) +{ + if(rc_screenCheck(s_num)) + { + *x = rc_screen_rect[rc_active_window][s_num].x; + *y = rc_screen_rect[rc_active_window][s_num].y; + *w = rc_screen_rect[rc_active_window][s_num].w; + *h = rc_screen_rect[rc_active_window][s_num].h; + } + else + cout << "GetScreenViewport Error: Screen #" << s_num << " is not accessible" << endl; +} + +void rc_media_screenOffset(int s_num, int x, int y) +{ + if(rc_screenCheck(s_num)) + { + //removed error checks because you only live once + rc_screenview[rc_active_window][s_num].x = x; + rc_screenview[rc_active_window][s_num].y = y; + rc_screenview[rc_active_window][s_num].w = rc_screen_rect[rc_active_window][s_num].w; + rc_screenview[rc_active_window][s_num].h = rc_screen_rect[rc_active_window][s_num].h; + //SDL_SetClipRect(rc_sscreen[rc_active_window][rc_active_screen], &rc_screenview[rc_active_window][rc_active_screen]); + } +} + +void rc_media_getScreenOffset(int s_num, double * x, double * y) +{ + if(rc_screenCheck(s_num)) + { + *x = rc_screenview[rc_active_window][s_num].x; + *y = rc_screenview[rc_active_window][s_num].y; + } +} + +void rc_media_getScreenSize(int s_num, double * w, double * h) +{ + if(rc_screenCheck(s_num)) + { + *w = rc_screen_width[rc_active_window][s_num]; + *h = rc_screen_height[rc_active_window][s_num]; + } +} + +void rc_media_clearScreen_hw() +{ + if(rc_screenCheck()) + { + //cout << "Clear screen\n"; + //SDL_LockSurface(rc_sscreen[rc_active_window][rc_active_screen]); + //SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + //SDL_RenderFillRect(rc_win_renderer[rc_active_window], &rc_screen_rect[rc_active_window][rc_active_screen]); + //SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + } +} + +void rc_media_setScreenAlpha_hw(int s_num, Uint8 alpha) +{ + if(rc_screenCheck(s_num)) + { + SDL_SetTextureAlphaMod(rc_hscreen[rc_active_window][s_num], alpha); + } +} + +Uint32 rc_media_ScreenAlpha_hw(int s_num) +{ + Uint8 alpha = 0; + if(rc_screenCheck(s_num)) + { + SDL_GetTextureAlphaMod(rc_hscreen[rc_active_window][s_num], &alpha); + } + return (Uint32)alpha; +} + +int rc_media_setScreenBlendMode_hw(int s_num, int blend_mode) +{ + if(!rc_screenCheck(s_num)) + { + return -1; + } + int rslt = -1; + SDL_BlendMode b = SDL_BLENDMODE_NONE; + switch(blend_mode) + { + case 0: //SDL_BLENDMODE_NONE + b = SDL_BLENDMODE_NONE; + break; + case 1: //SDL_BLENDMODE_BLEND + b = SDL_BLENDMODE_BLEND; + break; + case 2: //SDL_BLENDMODE_ADD + b = SDL_BLENDMODE_ADD; + break; + case 4: //SDL_BLENDMODE_MOD + b = SDL_BLENDMODE_MOD; + break; + default: + return rslt; + } + rslt = SDL_SetTextureBlendMode(rc_hscreen[rc_active_window][s_num], b); + + return rslt; +} + +int rc_media_screenBlendMode_hw(int s_num) +{ + if(!rc_screenCheck(s_num)) + { + return -1; + } + SDL_BlendMode blend_mode = SDL_BLENDMODE_NONE; + int rslt = SDL_GetTextureBlendMode(rc_hscreen[rc_active_window][s_num], &blend_mode); + if(rslt < 0) + { + cout << "CanvasBlendMode Error: " << SDL_GetError() << endl; + return rslt; + } + return blend_mode; +} + +int rc_media_setScreenColorMod_hw(int s_num, Uint32 c) +{ + if(!rc_screenCheck(s_num)) + { + return -1; + } + int rslt = -1; + + Uint8 r = c>>16; + Uint8 g = c>>8; + Uint8 b = c; + + //cout << "C = " << c << endl; + //cout << "RGB = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << endl; + + rslt = SDL_SetTextureColorMod(rc_hscreen[rc_active_window][s_num], r, g, b); + return rslt; +} + +int rc_media_screenColorMod_hw(int s_num) +{ + if(!rc_screenCheck(s_num)) + { + return -1; + } + + Uint8 r = 0; + Uint8 g = 0; + Uint8 b = 0; + int rslt = SDL_GetTextureColorMod(rc_hscreen[rc_active_window][s_num], &r, &g, &b); + + if(rslt < 0) + { + cout << "CanvasColorMode Error: " << SDL_GetError() << endl; + return rslt; + } + + Uint32 c_mod = (Uint32)SDL_MapRGBA(rc_pformat,r,g,b,255); + + //cout << "-RGB = " << (int)r << ", " << (int)g << ", " << (int)b << endl; + + return c_mod; +} +//---------------- + + +void rc_media_copyScreen_hw(int src_screen, int sx, int sy, int sw, int sh, int dst_screen, int dx, int dy) +{ + if(rc_screenCheck(src_screen) && rc_screenCheck(dst_screen)) + { + SDL_Rect src_rect, dst_rect; + src_rect.x = sx; + src_rect.y = sy; + src_rect.w = sw; + src_rect.h = sh; + dst_rect.x = dx; + dst_rect.y = dy; + dst_rect.w = sw; + dst_rect.h = sh; + //SDL_BlitSurface(rc_sscreen[rc_active_window][src_screen], &src_rect, rc_sscreen[rc_active_window][dst_screen], &dst_rect); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][dst_screen]); + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][src_screen], &src_rect, &dst_rect); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + } +} + +void rc_media_getScreenClip_hw(int slot, int sx, int sy, int sw, int sh) +{ + if(rc_screenCheck(rc_active_screen)) + { + SDL_RendererFlip rf = (SDL_RendererFlip)SDL_FLIP_NONE; + int w = 0; + int h = 0; + SDL_QueryTexture(rc_hscreen[rc_active_window][rc_active_screen], NULL, NULL, &w, &h); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, w, h); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], tmp_tex); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + SDL_Point center; + center.x = w/2; + center.y = h/2; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen], NULL, NULL, 0, ¢er,rf); + SDL_Surface * img_surf = SDL_CreateRGBSurface(0, sw, sh, 32, 0, 0, 0, 0); + SDL_Rect src_rect; + src_rect.x = sx; + src_rect.y = sy; + src_rect.w = sw; + src_rect.h = sh; + //SDL_BlitSurface(rc_sscreen[rc_active_window][src_screen], &src_rect, rc_sscreen[rc_active_window][dst_screen], &dst_rect); + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &src_rect, rc_pformat->format, img_surf->pixels, img_surf->pitch); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_DestroyTexture(tmp_tex); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win_renderer[i]!=NULL) + { + if(rc_himage[slot][i]!=NULL) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = NULL; + } + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], img_surf); + rc_himage_rect[slot].x = 0; + rc_himage_rect[slot].y = 0; + rc_himage_rect[slot].w = img_surf->w; + rc_himage_rect[slot].h = img_surf->h; + rc_image_width[slot] = img_surf->w; + rc_image_height[slot] = img_surf->h; + rc_image_isLoaded[slot] = true; + } + } + + SDL_FreeSurface(img_surf); + } +} + +void rc_media_getScreenClip2_hw(int slot, int sx, int sy, int sw, int sh, bool flag) +{ + if(!flag) + { + rc_media_getScreenClip_hw(slot, sx, sy, sw, sh); + } + else if(rc_screenCheck(rc_active_screen)) + { + if(rc_himage[slot][rc_active_window] != NULL) + { + cout << "CanvasClip_Ex Error: Image slot is already occupied" << endl; + return; + } + SDL_Rect src, dst; + rc_himage[slot][rc_active_window] = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, sw, sh); + src.x = sx; + src.y = sy; + src.w = sw; + src.h = sh; + dst.x = 0; + dst.y = 0; + dst.w = sw; + dst.h = sh; + rc_himage_rect[slot] = dst; + rc_image_width[slot] = sw; + rc_image_height[slot] = sh; + rc_image_isLoaded[slot] = true; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_himage[slot][rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], 0, 0, 0, 0); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen], &src, &dst); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + } +} + + + +void rc_media_getWindowClip_hw(int slot, int sx, int sy, int sw, int sh) +{ + SDL_Surface * img_surf = SDL_CreateRGBSurface(0, sw, sh, 32, 0, 0, 0, 0); + SDL_Rect src_rect; + src_rect.x = sx; + src_rect.y = sy; + src_rect.w = sw; + src_rect.h = sh; + //SDL_BlitSurface(rc_sscreen[rc_active_window][src_screen], &src_rect, rc_sscreen[rc_active_window][dst_screen], &dst_rect); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &src_rect, rc_pformat->format, img_surf->pixels, img_surf->pitch); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win_renderer[i]!=NULL) + { + if(rc_himage[slot][i]!=NULL) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = NULL; + } + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], img_surf); + rc_himage_rect[slot].x = 0; + rc_himage_rect[slot].y = 0; + rc_himage_rect[slot].w = img_surf->w; + rc_himage_rect[slot].h = img_surf->h; + rc_image_width[slot] = img_surf->w; + rc_image_height[slot] = img_surf->h; + rc_image_isLoaded[slot] = true; + } + } + + SDL_FreeSurface(img_surf); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); +} + +void rc_media_cloneScreen_hw(int src_screen, int dst_screen) +{ + if(rc_screenCheck(src_screen) && (dst_screen >= 0 && dst_screen < MAX_SCREENS)) + { + if(rc_hscreen[rc_active_window][dst_screen] == NULL) + { + rc_hscreen[rc_active_window][dst_screen] = rc_hscreen[rc_active_window][src_screen]; + rc_screen_width[rc_active_window][dst_screen] = rc_screen_width[rc_active_window][src_screen]; + rc_screen_height[rc_active_window][dst_screen] = rc_screen_height[rc_active_window][src_screen]; + rc_screen_rect[rc_active_window][dst_screen] = rc_screen_rect[rc_active_window][src_screen]; + rc_screenview[rc_active_window][dst_screen] = rc_screenview[rc_active_window][src_screen]; + rc_screen_visible[rc_active_window][dst_screen] = rc_screen_visible[rc_active_window][src_screen]; + } + } +} + +void rc_sortZ(int priority_screen) +{ + int aw = rc_active_window; + int draw_order = 0; + for(int z = 0; z < MAX_SCREENS; z++) + { + if(rc_screen_z[aw][priority_screen] == z) + { + rc_screen_zOrder[aw][draw_order] = priority_screen; + draw_order++; + } + for(int n = 0; n < MAX_SCREENS; n++) + { + if(rc_screen_z[aw][n] == z && n != priority_screen) + { + rc_screen_zOrder[aw][draw_order] = n; + draw_order++; + } + } + } +} + +void rc_media_setScreenZ(int s_num, int z) +{ + if(rc_screenCheck(s_num)) + { + if(z < 0 || z >= MAX_SCREENS) + { + cout << "SetScreenZ Error: Z Order must be a value from 0 to " << MAX_SCREENS-1 << endl; + return; + } + //int tmp_z = 0; + //int tmp_order[MAX_SCREENS]; + //cout << "z_start: " << rc_screen_zOrder[rc_active_window][rc_active_screen] << endl; + + rc_screen_z[rc_active_window][s_num] = z; + + rc_sortZ(s_num); + + //for(int i = 0; i < MAX_SCREENS; i++) + //cout << "z: " << rc_screen_zOrder[rc_active_window][i] << endl; + } +} + +int rc_media_screenZ(int s_num) +{ + if(rc_screenCheck(s_num)) + { + return rc_screen_z[rc_active_window][s_num]; + } + return -1; +} + +void rc_media_box_hw(int x1, int y1, int x2, int y2) +{ + Sint16 vx[4], vy[4]; + + vx[0] = (Sint16)x1; + vy[0] = (Sint16)y1; + + vx[1] = (Sint16)x2; + vy[1] = (Sint16)y1; + + vx[2] = (Sint16)x2; + vy[2] = (Sint16)y2; + + vx[3] = (Sint16)x1; + vy[3] = (Sint16)y2; + + polygonRGBA(rc_win_renderer[rc_active_window], vx, vy, 4, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_boxFill_hw(int x1, int y1, int x2, int y2) +{ + Sint16 vx[4], vy[4]; + + vx[0] = (Sint16)x1; + vy[0] = (Sint16)y1; + + vx[1] = (Sint16)x2; + vy[1] = (Sint16)y1; + + vx[2] = (Sint16)x2; + vy[2] = (Sint16)y2; + + vx[3] = (Sint16)x1; + vy[3] = (Sint16)y2; + + filledPolygonRGBA(rc_win_renderer[rc_active_window], vx, vy, 4, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_rectangle(int x, int y, int w, int h) +{ + SDL_Rect rect_dim; + rect_dim.x = x; + rect_dim.y = y; + rect_dim.w = w; + rect_dim.h = h; + + SDL_RenderDrawRect(rc_win_renderer[rc_active_window], &rect_dim); +} + +void rc_media_rectangleFill(int x, int y, int w, int h) +{ + SDL_Rect rect_dim; + rect_dim.x = x; + rect_dim.y = y; + rect_dim.w = w; + rect_dim.h = h; + + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &rect_dim); +} + +void rc_media_roundRect(int x, int y, int w, int h, int r) +{ + roundedRectangleRGBA(rc_win_renderer[rc_active_window], x, y, x+(w-1), y+(h-1), r, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_roundRectFill(int x, int y, int w, int h, int r) +{ + roundedBoxRGBA(rc_win_renderer[rc_active_window], x, y, x+(w-1), y+(h-1), r, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_circle_hw(int xc, int yc, int r) +{ + circleRGBA(rc_win_renderer[rc_active_window], xc, yc, r, rc_ink >> 16, rc_ink >> 8, rc_ink, rc_ink >> 24); +} + +void rc_media_circleFill_hw(int xc, int yc, int r) +{ + filledCircleRGBA(rc_win_renderer[rc_active_window], xc, yc, r, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_ellipse_hw(int xc, int yc, int width, int height) +{ + ellipseRGBA(rc_win_renderer[rc_active_window], xc, yc, width, height, rc_ink >> 16, rc_ink >> 8, rc_ink, rc_ink>>24); +} + +void rc_media_ellipseFill_hw(int xc, int yc, int width, int height) +{ + filledEllipseRGBA(rc_win_renderer[rc_active_window], xc, yc, width, height, rc_ink >> 16, rc_ink >> 8, rc_ink, rc_ink>>24); +} + +Uint32 rc_media_getPixel_hw(int x, int y) +{ + //Uint32 * s_pixels = (Uint32*) rc_win_surface[rc_active_window]->pixels; + #ifdef RC_MOBILE + SDL_Texture * tmp_buf = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_win_width[rc_active_window], rc_win_height[rc_active_window]); + if(tmp_buf==NULL) + return 0; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], tmp_buf); + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window], rc_backBuffer[rc_active_window], NULL, NULL, 0, NULL, rf); + #else + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + #endif // RC_MOBILE + + //cout << "surface = ( " << rc_win_surface[rc_active_window]->w << ", " << rc_win_surface[rc_active_window]->h << " ) " << endl; + //int w = 0; + //int h = 0; + //SDL_GetWindowSize(rc_win[rc_active_window], &w, &h); + //w = rc_displayMode[rc_active_window].w; + //h = rc_displayMode[rc_active_window].h; + Uint32 * s_pixels = (Uint32*)SDL_malloc(sizeof(Uint32)); + SDL_Rect p_rect; + #ifdef RC_MOBILE + p_rect.x = x; + p_rect.y = y; + #else + p_rect.x = x / rc_fullscreen_mouse_scale_x[rc_active_window]; + p_rect.y = y / rc_fullscreen_mouse_scale_y[rc_active_window]; + #endif // RC_MOBILE + p_rect.w = 1; + p_rect.h = 1; + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &p_rect, rc_pformat->format, (void*)s_pixels, 4); + + Uint32 p_color = s_pixels[0]; + + #ifdef RC_MOBILE + SDL_DestroyTexture(tmp_buf); + int r = p_color & 255; + int g = (p_color >> 8) & 255; + int b = (p_color >> 16) & 255; + int a = (p_color >> 24) & 255; + //p_color = SDL_MapRGBA(rc_pformat, r, g, b, a); + #endif // RC_MOBILE + + //cout << "color = " << p_color << endl; + SDL_free(s_pixels); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + return p_color; +} + +void rc_media_ink(Uint32 ink_color) +{ + //cout << "ink = " << ink_color << endl; + rc_ink = ink_color; + rc_ink_color.a = ink_color>>24;//ink_color >> 24; + //cout << "alpha = " << (int)rc_ink_color.a << endl; + rc_ink_color.r = ink_color >> 16; + rc_ink_color.g = ink_color >> 8; + rc_ink_color.b = ink_color; + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_setClearColor(Uint32 c_color) +{ + rc_clearColor = c_color; +} + +Uint32 rc_media_rgb(Uint8 r, Uint8 g, Uint8 b) +{ + //cout << "r = " << (int) r << " g = " << (int) g << " b = " << (int)b << endl; + Uint32 rgba_map = (Uint32)SDL_MapRGBA(rc_pformat,r,g,b,255); + //Uint32 rgba_map = (r << 16) + (g << 8) + b + (255 << 24);// + (255<<24); + //cout << "rgb_out = " << rgba_map << endl; + return rgba_map; +} + +Uint32 rc_media_rgba(Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + Uint32 rgba_map = (Uint32)SDL_MapRGBA(rc_pformat,r,g,b,a); + //rgba_map = rgba_map + (a<<24); + return rgba_map; +} + +void rc_media_line_hw(int x1, int y1, int x2, int y2) +{ + lineRGBA(rc_win_renderer[rc_active_window], x1, y1, x2, y2, rc_ink >> 16, rc_ink >> 8, rc_ink, rc_ink >> 24); +} + +void rc_getPrevColor(int x, int y) +{ + //cout << "PCOLOR #1" << endl; + Uint32 * s_pixels = (Uint32*)rc_sscreen[rc_active_window][rc_active_screen]->pixels; + //cout << "PCOLOR #2: " << y << " , " << rc_active_window << " , " << rc_active_screen << " , " << x << endl; + prev_color = s_pixels[y*rc_sscreen[rc_active_window][rc_active_screen]->w+x]; + //cout << "PCOLOR #3" << endl; +} + +void rc_media_floodFill_sw(int x, int y, Uint32* s_pixels, int pitch, int w) +{ + int s_lock = 0; + //cout << "u1" << endl; + if(SDL_MUSTLOCK(rc_sscreen[rc_active_window][rc_active_screen])) + { + //cout << "u2" << endl; + s_lock = 1; + SDL_LockSurface(rc_sscreen[rc_active_window][rc_active_screen]); + } + //cout << "u3" << endl; + //Uint32 * s_pixels = (Uint32*) rc_sscreen[rc_active_window][rc_active_screen]->pixels; + //cout << "u4" << endl; + //int pitch = rc_sscreen[rc_active_window][rc_active_screen]->pitch; + //cout << "u5" << endl; + //int w = rc_sscreen[rc_active_window][rc_active_screen]->pitch/4; + //cout << "u6" << endl; + + // Base cases + if (x < 0 || x >= rc_screen_width[rc_active_window][rc_active_screen] || y < 0 || y >= rc_screen_height[rc_active_window][rc_active_screen]) + return; + //cout << "u7" << endl; + if (s_pixels[y*w+x] != prev_color) + return; + //cout << "u8" << endl; + + // Replace the color at (x, y) + s_pixels[y*w+x] = rc_ink; + + //cout << "u8-1" << endl; cout << "x = " << x << "; y = " << y << endl; + + // Recur for north, east, south and west + rc_media_floodFill_sw(x+1, y, s_pixels, pitch, w); + rc_media_floodFill_sw(x-1, y, s_pixels, pitch, w); + rc_media_floodFill_sw(x, y+1, s_pixels, pitch, w); + rc_media_floodFill_sw(x, y-1, s_pixels, pitch, w); + + //cout << "u8-2" << endl; + + if(s_lock == 1) + { + //cout << "u9" << endl; + SDL_UnlockSurface(rc_sscreen[rc_active_window][rc_active_screen]); + //cout << "u10" << endl; + } +} + +void rc_media_floodFill_hw(int x, int y) +{ + rc_sscreen[rc_active_window][rc_active_screen] = SDL_CreateRGBSurface(0, rc_screen_width[rc_active_window][rc_active_screen], rc_screen_height[rc_active_window][rc_active_screen], 32, 0, 0, 0, 0); + SDL_Rect c_screen; + c_screen.x = 0; + c_screen.y = 0; + c_screen.w = rc_screen_width[rc_active_window][rc_active_screen]; + c_screen.h = rc_screen_height[rc_active_window][rc_active_screen]; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen],NULL,&c_screen); + //SDL_RendererFlip rf = (SDL_RendererFlip)SDL_FLIP_VERTICAL; + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen],NULL,NULL,0,NULL,rf); + + //cout << "DEBUG_FLOOD CP 1" << endl; + + if(SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &c_screen, rc_pformat->format,rc_sscreen[rc_active_window][rc_active_screen]->pixels,rc_sscreen[rc_active_window][rc_active_screen]->pitch) < 0) + { + cout << "ReadPixel Error: " << SDL_GetError() << endl; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + } + else + { + //cout << "DEBUG_FLOOD CP 2" << endl; + rc_getPrevColor(x, y); + //cout << "DEBUG_FLOOD CP 3" << endl; + Uint32 * s_pixels = (Uint32*) rc_sscreen[rc_active_window][rc_active_screen]->pixels; + int pitch = rc_sscreen[rc_active_window][rc_active_screen]->pitch; + int w = rc_sscreen[rc_active_window][rc_active_screen]->pitch/4; + //cout << "pitch = " << pitch << endl; + //cout << "w = " << w << endl; + //string bs=""; cin>>bs; + if(s_pixels[y*w+x] != rc_ink) + rc_media_floodFill_sw(x,y,s_pixels, pitch, w); + //cout << "DEBUG_FLOOD CP 4" << endl; + SDL_Texture * tmp_tex = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window], rc_sscreen[rc_active_window][rc_active_screen]); + //cout << "DEBUG_FLOOD CP 5" << endl; + + if(tmp_tex==NULL) + { + cout << "FloodFill Error: Canvas Buffer could not be created" << endl; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + } + else + { + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_RenderCopy(rc_win_renderer[rc_active_window],tmp_tex,NULL,NULL); + } + SDL_DestroyTexture(tmp_tex); + } + + SDL_FreeSurface(rc_sscreen[rc_active_window][rc_active_screen]); + rc_sscreen[rc_active_window][rc_active_screen] = NULL; + +} + +void rc_media_drawPixel_hw(int x, int y) +{ + pixelRGBA(rc_win_renderer[rc_active_window], x, y, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_poly(unsigned int n, double* vx_d, double* vy_d) +{ + Sint16 vx[n], vy[n]; + for(int i = 0; i < n; i++) + { + vx[i] = (Sint16)vx_d[i]; + vy[i] = (Sint16)vy_d[i]; + } + polygonRGBA(rc_win_renderer[rc_active_window], vx, vy, n, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_polyfill(unsigned int n, double* vx_d, double* vy_d) +{ + Sint16 vx[n], vy[n]; + for(int i = 0; i < n; i++) + { + vx[i] = (Sint16)vx_d[i]; + vy[i] = (Sint16)vy_d[i]; + } + filledPolygonRGBA(rc_win_renderer[rc_active_window], vx, vy, n, rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); +} + +void rc_media_loadImage_hw(int slot, string img_file) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "LoadImage Error: Image Slot must be in the range of 0 to " << MAX_IMAGES << endl; + return; + } + if(rc_himage[slot][rc_active_window]!=NULL) + { + cout << "LoadImage Error: Image " << slot << " is already in use" << endl; + return; + } + //mariocircuit-1.png + SDL_Surface * image = IMG_Load(img_file.c_str()); + if(image == NULL) + { + cout << "~Image: " << img_file.c_str() << endl; + cout << "LoadImage Error: " << IMG_GetError() << endl; + return; + } + #ifdef RC_MOBILE + SDL_Surface * image_cv = SDL_ConvertSurfaceFormat(image, rc_pformat->format, 0); + #else + SDL_Surface * image_cv = SDL_ConvertSurface(image, rc_pformat,0); + #endif // RC_MOBILE + rc_image_width[slot] = image_cv->w; + rc_image_height[slot] = image_cv->h; + rc_image_isLoaded[slot] = true; + if(image_cv == NULL) + { + cout << "LoadImage Error: " << SDL_GetError() << endl; + SDL_FreeSurface(image); + return; + } + + #ifdef RC_MOBILE + if(rc_himage[slot][rc_active_window] != NULL) + SDL_DestroyTexture(rc_himage[slot][rc_active_window]); + rc_himage[slot][rc_active_window] = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window], image_cv); + SDL_SetTextureBlendMode(rc_himage[slot][rc_active_window], SDL_BLENDMODE_BLEND); + #else + + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] != NULL) + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], image_cv); + SDL_SetTextureBlendMode(rc_himage[slot][i], SDL_BLENDMODE_BLEND); + if(i == rc_active_window && rc_himage[slot][rc_active_window] == NULL) + { + cout << "#LoadImage Error: " << SDL_GetError() << endl; + SDL_FreeSurface(image); + SDL_FreeSurface(image_cv); + for(int j = 0; j < i; j++) + SDL_DestroyTexture(rc_himage[slot][j]); + return; + } + } + + #endif // RC_MOBILE + SDL_FreeSurface(image); + SDL_FreeSurface(image_cv); +} + +void rc_media_loadImage_ex_hw(int slot, string img_file, double color) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "LoadImage_Ex Error: Image Slot must be in the range of 0 to " << MAX_IMAGES << endl; + return; + } + if(rc_himage[slot][rc_active_window]!=NULL) + { + cout << "LoadImage_Ex Error: Image Slot is already in use" << endl; + return; + } + SDL_Surface * image = IMG_Load(img_file.c_str()); + if(image == NULL) + { + cout << "LoadImage_Ex Error: " << SDL_GetError() << endl; + return; + } + + if(color < 0) + { + Uint32 * c = (Uint32*)image->pixels; + SDL_SetColorKey(image, SDL_TRUE, c[0]); + } + else + SDL_SetColorKey(image, SDL_TRUE, (Uint32)color); + + #ifdef RC_MOBILE + SDL_Surface * image_cv = SDL_ConvertSurfaceFormat(image, rc_pformat->format, 0); + #else + SDL_Surface * image_cv = SDL_ConvertSurface(image, rc_pformat,0); + #endif // RC_MOBILE + rc_image_width[slot] = image_cv->w; + rc_image_height[slot] = image_cv->h; + rc_image_isLoaded[slot] = true; + if(image_cv == NULL) + { + cout << "LoadImage_Ex Error: " << SDL_GetError() << endl; + SDL_FreeSurface(image); + return; + } + + #ifdef RC_MOBILE + if(rc_himage[slot][rc_active_window] != NULL) + SDL_DestroyTexture(rc_himage[slot][rc_active_window]); + rc_himage[slot][rc_active_window] = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window], image_cv); + SDL_SetTextureBlendMode(rc_himage[slot][rc_active_window], SDL_BLENDMODE_BLEND); + #else + + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] != NULL) + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], image_cv); + SDL_SetTextureBlendMode(rc_himage[slot][i], SDL_BLENDMODE_BLEND); + if(i == rc_active_window && rc_himage[slot][rc_active_window] == NULL) + { + cout << "#LoadImage_Ex Error: " << SDL_GetError() << endl; + SDL_FreeSurface(image); + SDL_FreeSurface(image_cv); + for(int j = 0; j < i; j++) + SDL_DestroyTexture(rc_himage[slot][j]); + return; + } + } + + #endif // RC_MOBILE + + SDL_FreeSurface(image); + SDL_FreeSurface(image_cv); +} + +void rc_media_createImage_hw(int slot, int w, int h, double * pdata) +{ + if(rc_himage[slot][rc_active_window] != NULL) + { + cout << "CreateImage Error: Image already exist" << endl; + return; + } + + SDL_Surface * img_surf = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); + Uint32 * img_pixels = (Uint32*)img_surf->pixels; + for(int i = 0; i < (w*h); i++) + { + img_pixels[i] = (Uint32)pdata[i]; + } + #ifdef RC_MOBILE + SDL_DestroyTexture(rc_himage[slot][rc_active_window]); + rc_himage[slot][rc_active_window] = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window], img_surf); + SDL_SetTextureBlendMode(rc_himage[slot][rc_active_window], SDL_BLENDMODE_BLEND); + + if(rc_himage[slot][rc_active_window] == NULL) + { + cout << "#CreateImage Error: " << SDL_GetError() << endl; + SDL_FreeSurface(img_surf); + SDL_DestroyTexture(rc_himage[slot][rc_active_window]); + return; + } + #else + for(int i = 0; i < MAX_WINDOWS; i++) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], img_surf); + SDL_SetTextureBlendMode(rc_himage[slot][i], SDL_BLENDMODE_BLEND); + } + if(rc_himage[slot][rc_active_window] == NULL) + { + cout << "#CreateImage Error: " << SDL_GetError() << endl; + SDL_FreeSurface(img_surf); + for(int j = 0; j < MAX_WINDOWS; j++) + { + SDL_DestroyTexture(rc_himage[slot][j]); + rc_himage[slot][j] = NULL; + } + return; + } + #endif // RC_MOBILE + rc_image_width[slot] = img_surf->w; + rc_image_height[slot] = img_surf->h; + rc_image_isLoaded[slot] = true; + SDL_FreeSurface(img_surf); +} + +void rc_media_createImage_Ex_hw(int slot, int w, int h, double * pdata, double color) +{ + if(rc_himage[slot][rc_active_window] != NULL) + { + cout << "CreateImage_Ex Error: Image already exist" << endl; + return; + } + + SDL_Surface * img_surf = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); + Uint32 * img_pixels = (Uint32*)img_surf->pixels; + for(int i = 0; i < (w*h); i++) + { + img_pixels[i] = (Uint32)pdata[i]; + } + #ifdef RC_MOBILE + SDL_Surface * image_cv = SDL_ConvertSurfaceFormat(img_surf, rc_pformat->format,0); + #else + SDL_Surface * image_cv = SDL_ConvertSurface(img_surf, rc_pformat,0); + #endif // RC_MOBILE + if(image_cv == NULL) + { + cout << "CreateImage_Ex Error: " << SDL_GetError() << endl; + SDL_FreeSurface(img_surf); + return; + } + if((Uint32)color<0) + SDL_SetColorKey(image_cv, SDL_TRUE, img_pixels[0]); + else + SDL_SetColorKey(image_cv, SDL_TRUE, (Uint32)color); + + #ifdef RC_MOBILE + SDL_DestroyTexture(rc_himage[slot][rc_active_window]); + rc_himage[slot][rc_active_window] = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window], image_cv); + SDL_SetTextureBlendMode(rc_himage[slot][rc_active_window], SDL_BLENDMODE_BLEND); + + if(rc_himage[slot][rc_active_window] == NULL) + { + cout << "#CreateImage_Ex Error: " << SDL_GetError() << endl; + SDL_FreeSurface(img_surf); + SDL_FreeSurface(image_cv); + SDL_DestroyTexture(rc_himage[slot][rc_active_window]); + rc_himage[slot][rc_active_window] = NULL; + return; + } + #else + for(int i = 0; i < MAX_WINDOWS; i++) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], image_cv); + SDL_SetTextureBlendMode(rc_himage[slot][i], SDL_BLENDMODE_BLEND); + } + if(rc_himage[slot][rc_active_window] == NULL) + { + cout << "#CreateImage_Ex Error: " << SDL_GetError() << endl; + SDL_FreeSurface(img_surf); + SDL_FreeSurface(image_cv); + for(int j = 0; j < MAX_WINDOWS; j++) + { + SDL_DestroyTexture(rc_himage[slot][j]); + rc_himage[slot][j] = NULL; + } + return; + } + #endif // RC_MOBILE + rc_image_width[slot] = image_cv->w; + rc_image_height[slot] = image_cv->h; + rc_image_isLoaded[slot] = true; + SDL_FreeSurface(img_surf); + SDL_FreeSurface(image_cv); +} + +void rc_media_bufferFromImage(int slot, double * pdata) +{ + SDL_Rect img_rect; + img_rect.x = 0; + img_rect.y = 0; + img_rect.w = rc_image_width[slot]; + img_rect.h = rc_image_height[slot]; + + //cout << "Debug data: " << img_rect.w << ", " << img_rect.h << endl; + + + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + //cout << "Colorkey = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << ", " << (Uint32)a << endl; + Uint32 * pxl = (Uint32*)tmp_surf->pixels; + + for(int y = 0; y < img_rect.h; y ++) + { + for(int x = 0; x < img_rect.w; x++) + { + pdata[y*img_rect.w+x] = pxl[y*img_rect.w+x]; + } + } + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_DestroyTexture(tmp_tex); + SDL_FreeSurface(tmp_surf); + +} + +#ifdef RC_IOS +void rc_media_colorKey_hw(int slot, double color) +{ + Uint32 c = (Uint32) color; + //Uint8 r = c >> 16; + //Uint8 g = c >> 8; + //Uint8 b = c; + //Uint8 a = c >> 24; + //c = SDL_MapRGBA(rc_win_surface[0]->format,r,g,b,255); + if(color > 0) + { + //return; + SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_NONE); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],tmp_tex); + //SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL); + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], NULL, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + //cout << "Colorkey = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << ", " << (Uint32)a << endl; + SDL_SetColorKey(tmp_surf,SDL_TRUE,c); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], tmp_surf); + } + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_DestroyTexture(tmp_tex); + SDL_FreeSurface(tmp_surf); + } + else + { + SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_NONE); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + //SDL_Surface * tmp_surf = SDL_ConvertSurfaceFormat(tmp_psurf, rc_pformat->format, 0); + //SDL_FreeSurface(tmp_psurf); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],tmp_tex); + //SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL); + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], NULL, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + //cout << "Colorkey = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << ", " << (Uint32)a << endl; + Uint32 * gcolor = (Uint32*)tmp_surf->pixels; + c = gcolor[0]; + SDL_SetColorKey(tmp_surf,SDL_TRUE,c); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], tmp_surf); + } + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_DestroyTexture(tmp_tex); + SDL_FreeSurface(tmp_surf); + } +} +#else +void rc_media_colorKey_hw(int slot, double color) +{ + Uint32 c = (Uint32) color; + //Uint8 r = c >> 16; + //Uint8 g = c >> 8; + //Uint8 b = c; + //Uint8 a = c >> 24; + //c = SDL_MapRGBA(rc_win_surface[0]->format,r,g,b,255); + SDL_Rect img_rect; + img_rect.x = 0; + img_rect.y = 0; + img_rect.w = rc_image_width[slot]; + img_rect.h = rc_image_height[slot]; + if(color >= 0) + { + //return; + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + //cout << "Colorkey = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << ", " << (Uint32)a << endl; + rc_image_colorKey[slot] = c; + rc_image_colorKey_r[slot] = c >> 16; + rc_image_colorKey_g[slot] = c >> 8; + rc_image_colorKey_b[slot] = c; + rc_image_colorKey_a[slot] = c >> 24; + + SDL_SetColorKey(tmp_surf,SDL_TRUE,c); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], tmp_surf); + } + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_DestroyTexture(tmp_tex); + SDL_FreeSurface(tmp_surf); + } + else + { + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + //cout << "Colorkey = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << ", " << (Uint32)a << endl; + Uint32 * pxl = (Uint32*)tmp_surf->pixels; + c = pxl[0]; + rc_image_colorKey[slot] = c; + rc_image_colorKey_r[slot] = c >> 16; + rc_image_colorKey_g[slot] = c >> 8; + rc_image_colorKey_b[slot] = c; + rc_image_colorKey_a[slot] = c >> 24; + SDL_SetColorKey(tmp_surf,SDL_TRUE,c); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], tmp_surf); + } + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_DestroyTexture(tmp_tex); + SDL_FreeSurface(tmp_surf); + } +} +#endif //RC_IOS + +void rc_media_deleteImage_hw(int slot) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "DeleteImage Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return; + } + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] == NULL) + continue; + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = NULL; + } + rc_image_isLoaded[slot] = false; + rc_image_width[slot] = 0; + rc_image_height[slot] = 0; +} + +void rc_media_setImageAlpha_hw(int slot, Uint8 alpha) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "SetImageAlpha Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "SetImageAlpha Error: Image Slot is empty" << endl; + return; + } + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] != NULL) + { + SDL_SetTextureAlphaMod(rc_himage[slot][i],alpha); + } + } +} + +int rc_media_getImageAlpha_hw(int slot) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "GetImageAlpha Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return -1; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "GetImageAlpha Error: Image Slot is empty" << endl; + return -1; + } + Uint8 a = 0; + SDL_GetTextureAlphaMod(rc_himage[slot][rc_active_window], &a); + return a; +} + +void rc_media_getImageSize_hw(int slot, double * w, double * h) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "GetImageSize Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "GetImageSize Error: Image Slot is empty" << endl; + *w = 0; + *h = 0; + return; + } + Uint32 format = 0; + int access = 0, width = 0, height = 0; + SDL_QueryTexture(rc_himage[slot][rc_active_window], &format, &access, &width, &height); + *w = width; + *h = height; +} + +int rc_media_setImageBlendMode_hw(int slot, int blend_mode) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "SetImageBlendMode Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return -1; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "SetImageBlendMode Error: Image Slot is empty" << endl; + return -1; + } + int rslt = -1; + SDL_BlendMode b = SDL_BLENDMODE_NONE; + switch(blend_mode) + { + case 0: //SDL_BLENDMODE_NONE + b = SDL_BLENDMODE_NONE; + break; + case 1: //SDL_BLENDMODE_BLEND + b = SDL_BLENDMODE_BLEND; + break; + case 2: //SDL_BLENDMODE_ADD + b = SDL_BLENDMODE_ADD; + break; + case 4: //SDL_BLENDMODE_MOD + b = SDL_BLENDMODE_MOD; + break; + default: + return rslt; + } + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] != NULL) + { + + rslt = SDL_SetTextureBlendMode(rc_himage[slot][i], b); + } + } + return rslt; +} + +int rc_media_imageBlendMode_hw(int slot) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "ImageBlendMode Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return -1; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "ImageBlendMode Error: Image Slot is empty" << endl; + return -1; + } + SDL_BlendMode blend_mode = SDL_BLENDMODE_NONE; + int rslt = SDL_GetTextureBlendMode(rc_himage[slot][rc_active_window], &blend_mode); + if(rslt < 0) + { + cout << "ImageBlendMode Error: " << SDL_GetError() << endl; + return rslt; + } + return blend_mode; +} + +int rc_media_setImageColorMod_hw(int slot, Uint32 c) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "SetImageColorMod Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return -1; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "SetImageColorMod Error: Image Slot is empty" << endl; + return -1; + } + int rslt = -1; + + Uint8 r = c>>16; + Uint8 g = c>>8; + Uint8 b = c; + + //cout << "C = " << c << endl; + //cout << "RGB = " << (Uint32)r << ", " << (Uint32)g << ", " << (Uint32)b << endl; + + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] != NULL) + { + + rslt = SDL_SetTextureColorMod(rc_himage[slot][i], r, g, b); + } + } + return rslt; +} + +int rc_media_imageColorMod_hw(int slot) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "ImageColorMod Error: Image Slot must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return -1; + } + if(rc_himage[slot][rc_active_window]==NULL) + { + cout << "ImageColorMod Error: Image Slot is empty" << endl; + return -1; + } + + Uint8 r = 0; + Uint8 g = 0; + Uint8 b = 0; + int rslt = SDL_GetTextureColorMod(rc_himage[slot][rc_active_window], &r, &g, &b); + + if(rslt < 0) + { + cout << "ImageColorMode Error: " << SDL_GetError() << endl; + return rslt; + } + + Uint32 c_mod = (Uint32)SDL_MapRGBA(rc_pformat,r,g,b,255); + + //cout << "-RGB = " << (int)r << ", " << (int)g << ", " << (int)b << endl; + + return c_mod; +} + +void rc_media_copyImage_hw(int src_slot, int dst_slot) +{ + //return; + if(src_slot < 0 || src_slot >= MAX_IMAGES || dst_slot < 0 || dst_slot >= MAX_IMAGES) + { + cout << "CopyImage Error: Image Slot should be in the range of 0 to " << MAX_IMAGES-1 << endl; + return; + } + if(rc_himage[src_slot][rc_active_window]!=NULL && rc_himage[dst_slot][rc_active_window]==NULL) + { + //rc_simage[dst_slot] = SDL_ConvertSurface(rc_simage[src_slot], rc_simage[src_slot]->format, 0); + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[src_slot], rc_image_height[src_slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], tmp_surf->format->format, SDL_TEXTUREACCESS_TARGET, tmp_surf->w, tmp_surf->h); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], tmp_tex); + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[src_slot][rc_active_window],NULL,NULL,0,NULL,rf); + SDL_RenderReadPixels(rc_win_renderer[rc_active_window],NULL,tmp_surf->format->format,tmp_surf->pixels,tmp_surf->pitch); + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[dst_slot][i] != NULL) + { + //cout << "slot " << dst_slot << " win " << i << endl; + SDL_DestroyTexture(rc_himage[dst_slot][i]); + rc_himage[dst_slot][i] = NULL; + } + rc_himage[dst_slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window],tmp_surf); + } + rc_image_width[dst_slot] = tmp_surf->w; + rc_image_height[dst_slot] = tmp_surf->h; + SDL_FreeSurface(tmp_surf); + SDL_DestroyTexture(tmp_tex); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen]); + rc_image_isLoaded[dst_slot] = true; + } + else + { + cout << "CopyImage Error: Image slot could not be used" << endl; + return; + } +} + +void rc_media_rotateImage_hw(int slot, int x, int y, double degrees) +{ + //double PI = 3.14159265359; + //double angle = degrees * PI/180; + //double theta = SDL_acos(rc_simage[0]->w/2+angle); + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = rc_image_width[slot]; + dst.h = rc_image_height[slot]; + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window], rc_himage[slot][rc_active_window], NULL, &dst, degrees, NULL, rf); +} + +void rc_media_rotateImageEX_hw(int slot, int x, int y, int src_x, int src_y, int src_w, int src_h, double degrees) +{ + //double PI = 3.14159265359; + //double angle = degrees * PI/180; + //double theta = SDL_acos(rc_simage[0]->w/2+angle); + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_Rect c_rect; + c_rect.x = src_x; + c_rect.y = src_y; + c_rect.w = src_w; + c_rect.h = src_h; + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = src_w; + dst.h = src_h; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],&c_rect, &dst,degrees,NULL,rf); +} + + +void rc_media_zoomImage_hw(int slot, int x, int y, double zoom_x, double zoom_y) +{ + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = rc_image_width[slot] * zoom_x; + dst.h = rc_image_height[slot] * zoom_y; + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_himage[slot][rc_active_window], NULL, &dst); +} + +void rc_media_zoomImageEX_hw(int slot, int x, int y, int src_x, int src_y, int src_w, int src_h, double zoom_x, double zoom_y) +{ + int zw = src_w * zoom_x; + int zh = src_h * zoom_y; + int ax = src_w/2 - zw/2, ay = src_h/2 - zh/2; + SDL_Rect r; + r.x = x+ax; r.y = y+ay; + r.w = zw; r.h = zh; + SDL_Rect s_rect; + s_rect.x = src_x; + s_rect.y = src_y; + s_rect.w = src_w; + s_rect.h = src_h; + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],&s_rect,&r,0,NULL,rf); +} + +void rc_media_rotozoomImage_hw(int slot, int x, int y, float degrees, float zoom_x, float zoom_y) +{ + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = rc_image_width[slot] * zoom_x; + dst.h = rc_image_height[slot] * zoom_y; + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&dst,degrees,NULL,rf); +} + +void rc_media_rotozoomImageEX_hw(int slot, int x, int y, int src_x, int src_y, int src_w, int src_h, float degrees, float zoom_x, float zoom_y) +{ + //cout << "src w,h = " << src_w << ", " << src_h << endl; + SDL_Rect src, dst; + src.x = src_x; + src.y = src_y; + src.w = src_w; + src.h = src_h; + dst.x = x; + dst.y = y; + dst.w = src_w * zoom_x; + dst.h = src_h * zoom_y; + SDL_RendererFlip rf = SDL_FLIP_NONE; + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],&src,&dst,degrees,NULL,rf); +} + +void rc_media_MirrorImage_hw(int slot, Uint8 flipH, Uint8 flipV) +{ + SDL_RendererFlip rf = SDL_FLIP_NONE; + if(flipH!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_HORIZONTAL); + if(flipV!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_VERTICAL); + SDL_Surface * m_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * m_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], m_surf->format->format,SDL_TEXTUREACCESS_TARGET,rc_image_width[slot],rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],m_tex); + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + SDL_RenderReadPixels(rc_win_renderer[rc_active_window],NULL,m_surf->format->format,m_surf->pixels,m_surf->pitch); + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win[i]!=NULL) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i],m_surf); + } + } + SDL_DestroyTexture(m_tex); + SDL_FreeSurface(m_surf); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen]); +} + +void rc_media_drawImage_hw(int slot, int x, int y) +{ + if(slot >= 0 && slot < MAX_IMAGES) + { + if(rc_hscreen[rc_active_window][rc_active_screen] == NULL) + { + cout << "DrawImage Error: Canvas #" << slot << " does not exist" << endl; + return; + } + SDL_Rect img_pos; + img_pos.x = x; + img_pos.y = y; + img_pos.w = rc_image_width[slot]; + img_pos.h = rc_image_height[slot]; + + if(SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_pos) < 0) + cout << "DrawImage error: " << SDL_GetError() << endl; + + } +} + +void rc_media_drawImage_Flip(int slot, int x, int y, int flipH, int flipV) +{ + SDL_RendererFlip rf = SDL_FLIP_NONE; + if(flipH!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_HORIZONTAL); + if(flipV!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_VERTICAL); + + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = rc_image_width[slot]; + dst.h = rc_image_height[slot]; + + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window], NULL, &dst, 0, NULL, rf); +} + +void rc_media_drawImage_Flip_Ex(int slot, int x, int y, int src_x, int src_y, int src_w, int src_h, int flipH, int flipV) +{ + SDL_RendererFlip rf = SDL_FLIP_NONE; + if(flipH!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_HORIZONTAL); + if(flipV!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_VERTICAL); + + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = rc_image_width[slot]; + dst.h = rc_image_height[slot]; + + SDL_Rect src; + src.x = src_x; + src.y = src_y; + src.w = src_w; + src.h = src_h; + + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window], &src, &dst, 0, NULL, rf); +} + +void rc_media_drawImage_Clip_hw(int slot, int x, int y, int src_x, int src_y, int src_w, int src_h) +{ + SDL_Rect src, dst; + src.x = src_x; + src.y = src_y; + src.w = src_w; + src.h = src_h; + dst.x = x; + dst.y = y; + dst.w = src_w; + dst.h = src_h; + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_himage[slot][rc_active_window], &src, &dst); +} + +void rc_media_drawImage_Blit_hw(int slot, int screen_x, int screen_y, int scale_w, int scale_h, int src_x, int src_y, int src_w, int src_h) +{ + SDL_Rect src, dst; + src.x = src_x; + src.y = src_y; + src.w = src_w; + src.h = src_h; + dst.x = screen_x; + dst.y = screen_y; + dst.w = scale_w; + dst.h = scale_h; + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_himage[slot][rc_active_window], &src, &dst); +} + +void rc_media_drawImage_Transform(int slot, int x, int y, int w, int h, int src_x, int src_y, int src_w, int src_h, double angle, int center_x, int center_y, int flipH, int flipV) +{ + SDL_RendererFlip rf = SDL_FLIP_NONE; + if(flipH!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_HORIZONTAL); + if(flipV!=0) + rf = (SDL_RendererFlip)(rf | SDL_FLIP_VERTICAL); + + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = w; + dst.h = h; + + SDL_Rect src; + src.x = src_x; + src.y = src_y; + src.w = src_w; + src.h = src_h; + + SDL_Point center; + center.x = center_x; + center.y = center_y; + + SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window], &src, &dst, angle, ¢er, rf); +} + +int SaveBMP(int slot, string file) +{ + SDL_Rect img_rect; + img_rect.x = 0; + img_rect.y = 0; + img_rect.w = rc_image_width[slot]; + img_rect.h = rc_image_height[slot]; + + //cout << "Debug data: " << img_rect.w << ", " << img_rect.h << endl; + + + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + + if(rc_active_screen >= 0 && rc_active_screen < MAX_SCREENS) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + SDL_DestroyTexture(tmp_tex); + + int ret_val = SDL_SaveBMP(tmp_surf, file.c_str()); + SDL_FreeSurface(tmp_surf); + + return ret_val; +} + +int SavePNG(int slot, string file) +{ + SDL_Rect img_rect; + img_rect.x = 0; + img_rect.y = 0; + img_rect.w = rc_image_width[slot]; + img_rect.h = rc_image_height[slot]; + + //cout << "Debug data: " << img_rect.w << ", " << img_rect.h << endl; + + + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + + if(rc_active_screen >= 0 && rc_active_screen < MAX_SCREENS) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + SDL_DestroyTexture(tmp_tex); + + int ret_val = IMG_SavePNG(tmp_surf, file.c_str()); + SDL_FreeSurface(tmp_surf); + + return ret_val; +} + +int SaveJPG(int slot, string file) +{ + SDL_Rect img_rect; + img_rect.x = 0; + img_rect.y = 0; + img_rect.w = rc_image_width[slot]; + img_rect.h = rc_image_height[slot]; + + //cout << "Debug data: " << img_rect.w << ", " << img_rect.h << endl; + + + //SDL_RendererFlip rf = (SDL_RendererFlip)(SDL_FLIP_VERTICAL); + + SDL_Surface * tmp_surf = SDL_CreateRGBSurface(0, rc_image_width[slot], rc_image_height[slot], 32, 0, 0, 0, 0); + SDL_Texture * tmp_tex = SDL_CreateTexture(rc_win_renderer[rc_active_window], rc_pformat->format, SDL_TEXTUREACCESS_TARGET, rc_image_width[slot], rc_image_height[slot]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,&img_rect); + //SDL_RenderCopyEx(rc_win_renderer[rc_active_window],rc_himage[slot][rc_active_window],NULL,NULL,0,NULL,rf); + + SDL_RenderReadPixels(rc_win_renderer[rc_active_window], &img_rect, rc_pformat->format,tmp_surf->pixels,tmp_surf->pitch); + + if(rc_active_screen >= 0 && rc_active_screen < MAX_SCREENS) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + + SDL_DestroyTexture(tmp_tex); + + int ret_val = IMG_SaveJPG(tmp_surf, file.c_str(), 100); + SDL_FreeSurface(tmp_surf); + + return ret_val; +} + + +#ifdef RC_WEB +int rc_media_drawGeometry(int slot, int num_vertices, double* vertices, int num_indices, double* indices) +{ + return 0; +} +#else +int rc_media_drawGeometry(int slot, int num_vertices, double* vertices, int num_indices, double* indices) +{ + SDL_Vertex geo_vert[( num_vertices >= 1 ? num_vertices : 1)]; + + int vert_size = 8; + + for(int i = 0; i < num_vertices; i++) + { + geo_vert[i].position.x = vertices[i*vert_size+0]; + geo_vert[i].position.y = vertices[i*vert_size+1]; + geo_vert[i].color.r = (Uint8)vertices[i*vert_size+2]; + geo_vert[i].color.g = (Uint8)vertices[i*vert_size+3]; + geo_vert[i].color.b = (Uint8)vertices[i*vert_size+4]; + geo_vert[i].color.a = (Uint8)vertices[i*vert_size+5]; + geo_vert[i].tex_coord.x = vertices[i*vert_size+6]; + geo_vert[i].tex_coord.y = vertices[i*vert_size+7]; + } + + int geo_index[(num_indices <= 0 ? 1 : num_indices)]; + + for(int i = 0; i < num_indices; i++) + { + geo_index[i] = (int) indices[i]; + } + + return SDL_RenderGeometry(rc_win_renderer[rc_active_window], + (slot >= 0 ? rc_himage[slot][rc_active_window] : NULL), + geo_vert, num_vertices, + (num_indices <= 0 ? NULL : geo_index), num_indices); +} +#endif //RC_WEB + +void rc_media_getCursor(double * x, double * y) +{ + *x = rc_sConsole_x[rc_active_window]; + *y = rc_sConsole_y[rc_active_window]; +} + +void rc_media_showCursor() +{ + rc_cursor_visible = 1; +} + +void rc_media_hideCursor() +{ + rc_cursor_visible = 0; +} + +void rc_media_locate(int x, int y) +{ + rc_sConsole_x[rc_active_window] = x; + rc_sConsole_y[rc_active_window] = y; +} + +string rc_fillSpace(int n) +{ + string s = ""; + for(int i = 0; i < n; i++) + s.append(" "); + return s; +} + +void rc_append_sConsole(string txt) +{ + string tc = txt; + string t_out[rc_console_height[rc_active_window]]; + + int i = 0; + + if(rc_sConsole_x[rc_active_window] >= rc_console_width[rc_active_window]) + rc_sConsole_x[rc_active_window] = 0; + + while(tc.compare("")!=0) + { + if(tc.substr(i).length() > ( rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]) ) + { + t_out[i] = rc_fillSpace(rc_sConsole_x[rc_active_window]) + tc.substr(i, rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]); + rc_sConsole_x[rc_active_window] = 0; + tc = tc.substr( (rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]) ); + i++; + } + else + { + t_out[i] = rc_fillSpace(rc_sConsole_x[rc_active_window]) + tc; + rc_sConsole_x[rc_active_window] = 0; + i++; + break; + } + } + + rc_sConsole_y[rc_active_window] += i; +} + +#ifdef RC_MOBILE +void rc_media_cls() +{ + if(rc_winCheck(rc_active_window)) + { + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_backBuffer[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], 0, 0, 0, 0); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + rc_media_ink(rc_ink); + } +} + +void rc_media_printS_hw(string txt) +{ + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + + string tc = txt; + string t_out[rc_console_height[rc_active_window]]; + + int i = 0; + + if(rc_sConsole_x[rc_active_window] >= rc_console_width[rc_active_window]) + rc_sConsole_x[rc_active_window] = 0; + + while(tc.compare("")!=0) + { + if(tc.substr(i).length() > ( rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]) ) + { + t_out[i] = rc_fillSpace(rc_sConsole_x[rc_active_window]) + tc.substr(i, rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]); + rc_sConsole_x[rc_active_window] = 0; + tc = tc.substr( (rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]) ); + i++; + } + else + { + t_out[i] = rc_fillSpace(rc_sConsole_x[rc_active_window]) + tc; + rc_sConsole_x[rc_active_window] = 0; + i++; + break; + } + } + + for(int n = 0; n < i; n++) + stringRGBA(rc_win_renderer[rc_active_window], 0, (rc_sConsole_y[rc_active_window] + n) * 8, t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + rc_sConsole_y[rc_active_window] += i; + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_hconsole[rc_active_window],NULL,NULL); + + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + return; +} + +string rc_media_inputS_hw(string prompt) +{ + SDL_Surface * input_surface = NULL; + SDL_Texture * input_texture = NULL; + bool loop = true; + SDL_Event in_evt; + string in_buf = prompt; + string rtn_string = ""; + string tc = in_buf; + string t_out[rc_console_height[rc_active_window]]; + int i = 0; + SDL_Rect first_line, sub_line; + first_line.x = (rc_sConsole_x[rc_active_window] * 8) + (prompt.length()*8); + first_line.y = rc_sConsole_y[rc_active_window] * 8; + first_line.w = 0; + first_line.h = 8; + sub_line.x = 0; + sub_line.y = (rc_sConsole_y[rc_active_window]+1) * 8; + sub_line.w = 0; + sub_line.h = 8; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + SDL_Rect txt_rect; + txt_rect = first_line; + txt_rect.w = 128; + txt_rect.h = 128; + //SDL_SetTextInputRect(&txt_rect); + + SDL_StartTextInput(); + + while(loop) + { + while(SDL_PollEvent(&in_evt)) + { + switch(in_evt.type) + { + case SDL_TEXTINPUT: + in_buf += in_evt.text.text; + break; + case SDL_KEYDOWN: + switch(in_evt.key.keysym.sym) + { + case SDLK_RETURN: + loop = false; + break; + case SDLK_BACKSPACE: + if(in_buf.length()-1 >= prompt.length() && in_buf.length()-1 >= 0) + in_buf = in_buf.substr(0, in_buf.length()-1); + break; + } + } + } + if(in_buf.length()>0) + { + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hconsole[rc_active_window]); + tc = in_buf; + i = 0; + int x = rc_sConsole_x[rc_active_window]; + if(x >= rc_console_width[rc_active_window]) + x = 0; + + while(tc.compare("")!=0) + { + if(tc.length() > ( rc_console_width[rc_active_window] - x) ) + { + t_out[i] = rc_fillSpace(x) + tc.substr(0, rc_console_width[rc_active_window] - x); + if(i == 0 && ((t_out[i].length() - prompt.length() - x)*8) > first_line.w) + { + first_line.w = (t_out[i].length() - prompt.length() - x) * 8; + } + else if(i != 0 && (t_out[i].length() * 8) > sub_line.w) + { + sub_line.w = t_out[i].length() * 8; + } + tc = tc.substr( (rc_console_width[rc_active_window] - x) ); + x = 0; + i++; + } + else + { + t_out[i] = rc_fillSpace(x) + tc; + if(i == 0 && ((t_out[i].length() - prompt.length() - x)*8) > first_line.w) + { + first_line.w = (t_out[i].length() - prompt.length() - x) * 8; + } + else if(i != 0 && (t_out[i].length() * 8) > sub_line.w) + { + sub_line.w = t_out[i].length() * 8; + } + x = 0; + i++; + break; + } + if(i >= rc_console_height[rc_active_window]) + break; + } + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, 255); + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &first_line); + + if(((i-1)*8) > sub_line.h) + sub_line.h = i*8; + + if(sub_line.h > 0) + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &sub_line); + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + for(int n = 0; n < i; n++) + { + stringRGBA(rc_win_renderer[rc_active_window], 0, (rc_sConsole_y[rc_active_window] + n) * 8, t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, 255);//rc_ink_color.a); + } + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window],rc_hconsole[rc_active_window],NULL,NULL); + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + } + } + SDL_StopTextInput(); + rc_sConsole_y[rc_active_window] += i; + rc_sConsole_x[rc_active_window] = 0; + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen]); + return in_buf.substr(prompt.length()); +} + +string rc_media_ZoneInputS_hw(int x, int y, int w, int h) +{ + SDL_Surface * input_surface = NULL; + SDL_Texture * input_texture = NULL; + bool loop = true; + SDL_Event in_evt; + string in_buf = ""; + string rtn_string = ""; + string tc = ""; + string t_out[rc_console_height[rc_active_window]]; + int i = 0; + SDL_Rect zone; + zone.x = x; + zone.y = y; + zone.w = w; + zone.h = h; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + SDL_StartTextInput(); + while(loop) + { + if(SDL_PollEvent(&in_evt)) + { + switch(in_evt.type) + { + case SDL_TEXTINPUT: + in_buf += in_evt.text.text; + break; + case SDL_KEYDOWN: + switch(in_evt.key.keysym.sym) + { + case SDLK_RETURN: + loop = false; + break; + case SDLK_BACKSPACE: + if(in_buf.length()-1 >= 0) + in_buf = in_buf.substr(0, in_buf.length()-1); + break; + } + } + } + if(in_buf.length()>=0) + { + tc = in_buf; + i = 0; + + while(tc.compare("")!=0) + { + if(tc.length() > (w/8) ) + { + t_out[i] = tc.substr(0, (w/8) ); + tc = tc.substr( w/8 ); + i++; + } + else + { + t_out[i] = tc; + i++; + break; + } + + if(i >= rc_console_height[rc_active_window]) + break; + } + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &zone); + + //cout << "zone txt color = " << (int)rc_ink_color.r << ", " << (int)rc_ink_color.g << ", " << (int)rc_ink_color.b << ", " << (int)rc_ink_color.a << endl; + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + //cout << "n < " << (int) (h/8) << endl; + + for(int n = 0; n < (h/8) && n < i; n++) + { + stringRGBA(rc_win_renderer[rc_active_window], x, y + (n * 8), t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + } + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window], NULL, NULL); + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + } + } + SDL_StopTextInput(); + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen]); + return in_buf; +} +#else + +void rc_media_cls() +{ + if(rc_winCheck(rc_active_window)) + { + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], 0, 0, 0, 0); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + rc_media_ink(rc_ink); + } +} + +void rc_media_printS_hw(string txt) +{ + if(rc_active_window < 0) + return; + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + + string tc = txt; + string t_out[rc_console_height[rc_active_window]]; + + int i = 0; + + if(rc_sConsole_x[rc_active_window] >= rc_console_width[rc_active_window]) + rc_sConsole_x[rc_active_window] = 0; + + while(tc.compare("")!=0) + { + if(tc.substr(i).length() > ( rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]) ) + { + t_out[i] = rc_fillSpace(rc_sConsole_x[rc_active_window]) + tc.substr(i, rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]); + rc_sConsole_x[rc_active_window] = 0; + tc = tc.substr( (rc_console_width[rc_active_window] - rc_sConsole_x[rc_active_window]) ); + i++; + } + else + { + t_out[i] = rc_fillSpace(rc_sConsole_x[rc_active_window]) + tc; + rc_sConsole_x[rc_active_window] = 0; + i++; + break; + } + } + + for(int n = 0; n < i; n++) + stringRGBA(rc_win_renderer[rc_active_window], 0, (rc_sConsole_y[rc_active_window] + n) * 8, t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + rc_sConsole_y[rc_active_window] += i; + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window], NULL, NULL); + + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + if(rc_active_screen>=0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + return; +} + +string rc_media_inputS_hw(string prompt) +{ + //SDL_Surface * input_surface = NULL; + //SDL_Texture * input_texture = NULL; + bool loop = true; + SDL_Event in_evt; + string in_buf = prompt; + string rtn_string = ""; + string tc = in_buf; + string t_out[rc_console_height[rc_active_window]]; + int i = 0; + SDL_Rect first_line, sub_line; + first_line.x = (rc_sConsole_x[rc_active_window] * 8) + (prompt.length()*8); + first_line.y = rc_sConsole_y[rc_active_window] * 8; + first_line.w = 0; + first_line.h = 8; + sub_line.x = 0; + sub_line.y = (rc_sConsole_y[rc_active_window]+1) * 8; + sub_line.w = 0; + sub_line.h = 8; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + + if(in_buf.length()>0) + { + tc = in_buf; + i = 0; + int x = rc_sConsole_x[rc_active_window]; + if(x >= rc_console_width[rc_active_window]) + x = 0; + + while(tc.compare("")!=0) + { + if(tc.length() > ( rc_console_width[rc_active_window] - x) ) + { + t_out[i] = rc_fillSpace(x) + tc.substr(0, rc_console_width[rc_active_window] - x); + if(i == 0 && ((t_out[i].length() - prompt.length() - x)*8) > first_line.w) + { + first_line.w = (t_out[i].length() - prompt.length() - x) * 8; + } + else if(i != 0 && (t_out[i].length() * 8) > sub_line.w) + { + sub_line.w = t_out[i].length() * 8; + } + tc = tc.substr( (rc_console_width[rc_active_window] - x) ); + x = 0; + i++; + } + else + { + t_out[i] = rc_fillSpace(x) + tc; + if(i == 0 && ((t_out[i].length() - prompt.length() - x)*8) > first_line.w) + { + first_line.w = (t_out[i].length() - prompt.length() - x) * 8; + } + else if(i != 0 && (t_out[i].length() * 8) > sub_line.w) + { + sub_line.w = t_out[i].length() * 8; + } + x = 0; + i++; + break; + } + if(i >= rc_console_height[rc_active_window]) + break; + } + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &first_line); + + if(((i-1)*8) > sub_line.h) + sub_line.h = i*8; + + if(sub_line.h > 0) + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &sub_line); + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + for(int n = 0; n < i; n++) + { + stringRGBA(rc_win_renderer[rc_active_window], 0, (rc_sConsole_y[rc_active_window] + n) * 8, t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + } + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + } + + while(loop) + { + if(SDL_WaitEvent(&in_evt)) + { + switch(in_evt.type) + { + case SDL_TEXTINPUT: + in_buf += in_evt.text.text; + break; + case SDL_KEYDOWN: + switch(in_evt.key.keysym.sym) + { + case SDLK_RETURN: + loop = false; + break; + case SDLK_BACKSPACE: + if(in_buf.length()-1 >= prompt.length() && in_buf.length()-1 >= 0) + in_buf = in_buf.substr(0, in_buf.length()-1); + break; + } + } + } + if(in_buf.length()>0) + { + tc = in_buf; + i = 0; + int x = rc_sConsole_x[rc_active_window]; + if(x >= rc_console_width[rc_active_window]) + x = 0; + + while(tc.compare("")!=0) + { + if(tc.length() > ( rc_console_width[rc_active_window] - x) ) + { + t_out[i] = rc_fillSpace(x) + tc.substr(0, rc_console_width[rc_active_window] - x); + if(i == 0 && ((t_out[i].length() - prompt.length() - x)*8) > first_line.w) + { + first_line.w = (t_out[i].length() - prompt.length() - x) * 8; + } + else if(i != 0 && (t_out[i].length() * 8) > sub_line.w) + { + sub_line.w = t_out[i].length() * 8; + } + tc = tc.substr( (rc_console_width[rc_active_window] - x) ); + x = 0; + i++; + } + else + { + t_out[i] = rc_fillSpace(x) + tc; + if(i == 0 && ((t_out[i].length() - prompt.length() - x)*8) > first_line.w) + { + first_line.w = (t_out[i].length() - prompt.length() - x) * 8; + } + else if(i != 0 && (t_out[i].length() * 8) > sub_line.w) + { + sub_line.w = t_out[i].length() * 8; + } + x = 0; + i++; + break; + } + if(i >= rc_console_height[rc_active_window]) + break; + } + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &first_line); + + if(((i-1)*8) > sub_line.h) + sub_line.h = i*8; + + if(sub_line.h > 0) + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &sub_line); + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + for(int n = 0; n < i; n++) + { + stringRGBA(rc_win_renderer[rc_active_window], 0, (rc_sConsole_y[rc_active_window] + n) * 8, t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + } + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window], NULL, NULL); + + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + } + } + rc_sConsole_y[rc_active_window] += i; + rc_sConsole_x[rc_active_window] = 0; + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen]); + return in_buf.substr(prompt.length()); +} + +string rc_media_ZoneInputS_hw(int x, int y, int w, int h) +{ + //SDL_Surface * input_surface = NULL; + //SDL_Texture * input_texture = NULL; + bool loop = true; + SDL_Event in_evt; + string in_buf = ""; + string rtn_string = ""; + string tc = ""; + string t_out[rc_console_height[rc_active_window]]; + int i = 0; + SDL_Rect zone; + zone.x = x; + zone.y = y; + zone.w = w; + zone.h = h; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + while(loop) + { + if(SDL_WaitEvent(&in_evt)) + { + switch(in_evt.type) + { + case SDL_TEXTINPUT: + in_buf += in_evt.text.text; + break; + case SDL_KEYDOWN: + switch(in_evt.key.keysym.sym) + { + case SDLK_RETURN: + loop = false; + break; + case SDLK_BACKSPACE: + if(in_buf.length()-1 >= 0) + in_buf = in_buf.substr(0, in_buf.length()-1); + break; + } + } + } + if(in_buf.length()>=0) + { + tc = in_buf; + i = 0; + + while(tc.compare("")!=0) + { + if(tc.length() > (w/8) ) + { + t_out[i] = tc.substr(0, (w/8) ); + tc = tc.substr( w/8 ); + i++; + } + else + { + t_out[i] = tc; + i++; + break; + } + + if(i >= rc_console_height[rc_active_window]) + break; + } + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor>>16, rc_clearColor>>8, rc_clearColor, rc_clearColor>>24); + SDL_RenderFillRect(rc_win_renderer[rc_active_window], &zone); + + //cout << "zone txt color = " << (int)rc_ink_color.r << ", " << (int)rc_ink_color.g << ", " << (int)rc_ink_color.b << ", " << (int)rc_ink_color.a << endl; + + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + //cout << "n < " << (int) (h/8) << endl; + + for(int n = 0; n < (h/8) && n < i; n++) + { + stringRGBA(rc_win_renderer[rc_active_window], x, y + (n * 8), t_out[n].c_str(), rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + } + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window], NULL, NULL); + + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window]); + } + } + if(rc_active_screen >= 0) + SDL_SetRenderTarget(rc_win_renderer[rc_active_window],rc_hscreen[rc_active_window][rc_active_screen]); + return in_buf; +} + +#endif // RC_MOBILE + +bool rc_media_fontIsLoaded(int slot) +{ + if(rc_draw_font[slot]!=NULL) + return true; + return false; +} + +void rc_media_font(int slot) +{ + if(rc_draw_font[slot]!= NULL) + rc_active_font = slot; +} + +void rc_media_setFontStyle(int f_slot, int style) +{ + TTF_SetFontStyle(rc_draw_font[f_slot], style); +} + +void rc_media_LoadFont(int slot, string font_path, int font_size) +{ + if(rc_draw_font[slot] != NULL) + TTF_CloseFont(rc_draw_font[slot]); + rc_draw_font[slot] = TTF_OpenFont(font_path.c_str(), font_size); + if(rc_active_font == -1) + rc_active_font = slot; +} + +void rc_media_DeleteFont(int slot) +{ + if(rc_draw_font[slot] != NULL) + TTF_CloseFont(rc_draw_font[slot]); + rc_draw_font[slot] = NULL; +} + +void rc_media_drawText_hw(string text, int x, int y) +{ + if(rc_draw_font[rc_active_font] == NULL) + { + cout << "DrawTextError: Could not load font at " << rc_active_font << endl; + return; + } + SDL_Surface * rendered_text = TTF_RenderUTF8_Solid(rc_draw_font[rc_active_font], text.c_str(), rc_ink_color); + //cout << "debug 1\n"; + SDL_Rect pos; + pos.x = x; + pos.y = y; + pos.w = rendered_text->w; + pos.h = rendered_text->h; + SDL_Texture * txt_image = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window],rendered_text); + //SDL_BlitSurface(rendered_text, NULL, rc_sscreen[rc_active_window][rc_active_screen], &pos); + SDL_FreeSurface(rendered_text); + SDL_RenderCopy(rc_win_renderer[rc_active_window],txt_image,NULL,&pos); + SDL_DestroyTexture(txt_image); +} + +void rc_media_drawText_shaded_hw(string text, int x, int y, Uint32 fg_color, Uint32 bg_color) +{ + if(rc_draw_font[rc_active_font] == NULL) + { + cout << "DrawTextError: Could not load font at " << rc_active_font << endl; + return; + } + SDL_Color fg, bg; + fg.a = fg_color >> 24; + fg.r = fg_color >> 16; + fg.g = fg_color >> 8; + fg.b = fg_color; + bg.a = bg_color >> 24; + bg.r = bg_color >> 16; + bg.g = bg_color >> 8; + bg.b = bg_color; + SDL_Surface * rendered_text = TTF_RenderUTF8_Shaded(rc_draw_font[rc_active_font], text.c_str(), fg, bg); + //cout << "debug 1\n"; + SDL_Rect pos; + pos.x = x; + pos.y = y; + pos.w = rendered_text->w; + pos.h = rendered_text->h; + SDL_Texture * txt_image = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window],rendered_text); + //SDL_BlitSurface(rendered_text, NULL, rc_sscreen[rc_active_window][rc_active_screen], &pos); + SDL_FreeSurface(rendered_text); + SDL_RenderCopy(rc_win_renderer[rc_active_window],txt_image,NULL,&pos); + SDL_DestroyTexture(txt_image); +} + +void rc_media_drawText_blended_hw(string text, int x, int y) +{ + if(rc_draw_font[rc_active_font] == NULL) + { + cout << "DrawTextError: Could not load font at " << rc_active_font << endl; + return; + } + SDL_Surface * rendered_text = TTF_RenderUTF8_Blended(rc_draw_font[rc_active_font], text.c_str(), rc_ink_color); + //cout << "debug 1\n"; + SDL_Rect pos; + pos.x = x; + pos.y = y; + pos.w = rendered_text->w; + pos.h = rendered_text->h; + SDL_Texture * txt_image = SDL_CreateTextureFromSurface(rc_win_renderer[rc_active_window],rendered_text); + //SDL_BlitSurface(rendered_text, NULL, rc_sscreen[rc_active_window][rc_active_screen], &pos); + SDL_FreeSurface(rendered_text); + SDL_RenderCopy(rc_win_renderer[rc_active_window],txt_image,NULL,&pos); + SDL_DestroyTexture(txt_image); +} + +void rc_media_getTextSize(int f_slot, string txt, double * w, double * h) +{ + if(rc_draw_font[f_slot] == NULL) + { + cout << "GetTextSize Error: No font at " << f_slot << endl; + return; + } + int txt_w = 0, txt_h = 0; + TTF_SizeUTF8(rc_draw_font[f_slot], txt.c_str(), &txt_w, &txt_h); + *w = txt_w; + *h = txt_h; +} + +void rc_media_GetRenderedText_hw(int slot, string text) +{ + if(slot < 0 || slot >= MAX_IMAGES) + { + cout << "GetRenderedText Error: Image must be in the range of 0 to " << MAX_IMAGES-1 << endl; + return; + } + if(rc_draw_font[rc_active_font] == NULL) + { + cout << "GetRenderedText Error: Could not load font at " << rc_active_font << endl; + return; + } + SDL_Surface * rendered_text = TTF_RenderUTF8_Solid(rc_draw_font[rc_active_font], text.c_str(), rc_ink_color); + + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_himage[slot][i] != NULL) + { + SDL_DestroyTexture(rc_himage[slot][i]); + rc_himage[slot][i] = NULL; + } + if(rc_win[i] != NULL) + { + rc_himage[slot][i] = SDL_CreateTextureFromSurface(rc_win_renderer[i], rendered_text); + rc_himage_rect[slot].x = 0; + rc_himage_rect[slot].y = 0; + rc_himage_rect[slot].w = rendered_text->w; + rc_himage_rect[slot].h = rendered_text->h; + rc_image_width[slot] = rendered_text->w; + rc_image_height[slot] = rendered_text->h; + rc_image_isLoaded[slot] = true; + } + } + + SDL_FreeSurface(rendered_text); +} + +std::string rc_utf8_substr(const std::string& str, unsigned int start, unsigned int leng) +{ + if (leng==0) { return ""; } + unsigned int c, i, ix, q, min=std::string::npos, max=std::string::npos; + for (q=0, i=0, ix=str.length(); i < ix; i++, q++) + { + if (q==start){ min=i; } + if (q<=start+leng || leng==std::string::npos){ max=i; } + + c = (unsigned char) str[i]; + if ( + //c>=0 && + c<=127) i+=0; + else if ((c & 0xE0) == 0xC0) i+=1; + else if ((c & 0xF0) == 0xE0) i+=2; + else if ((c & 0xF8) == 0xF0) i+=3; + //else if (($c & 0xFC) == 0xF8) i+=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8 + //else if (($c & 0xFE) == 0xFC) i+=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8 + else return "";//invalid utf8 + } + if (q<=start+leng || leng==std::string::npos){ max=i; } + if (min==std::string::npos || max==std::string::npos) { return ""; } + return str.substr(min,max-min); +} + +std::size_t rc_utf8_length(std::string const &s) +{ + return std::count_if(s.begin(), s.end(), + [](char c) { return (static_cast(c) & 0xC0) != 0x80; } ); +} + +int rc_getEvents() +{ + SDL_Event event; + int g_events = SDL_PollEvent(&event); + //int g_events = SDL_WaitEvent(&event); + //cout << "G_EVENT = " << g_events << endl; + //cout << "TYPE = " << event.type << endl; + if(!g_events) + return 0; + switch(event.type) + { + case SDL_QUIT: + SDL_PumpEvents(); + //rc_media_quit(); + exit(0); + break; + case SDL_WINDOWEVENT: + if(event.window.event == SDL_WINDOWEVENT_RESIZED) + { + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win_id[i] == event.window.windowID) + { + rc_active_window = i; + rc_win_event[i] = 4; + rc_onResize(rc_active_window); + break; + } + } + } + else if(event.window.event == SDL_WINDOWEVENT_CLOSE) + { + Uint32 win_id = -1; + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win[i]) + { + win_id = SDL_GetWindowID(rc_win[i]); + if(win_id == event.window.windowID) + { + rc_win_event[i] = 1; + if(SDL_QuitRequested() != 0) + { + //SDL_PumpEvents(); + SDL_FlushEvent(SDL_QUIT); + } + if(rc_win_exitOnClose[i]) + { + rc_media_closeWindow_hw(i); + return 0; + //rc_win_event[i] = 0; + } + break; + } + win_id = -1; + } + } + } + else if(event.window.event == SDL_WINDOWEVENT_MINIMIZED) + { + Uint32 win_id = -1; + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win[i]) + { + win_id = SDL_GetWindowID(rc_win[i]); + if(win_id == event.window.windowID) + { + rc_win_event[i] = 2; + //rc_media_closeWindow_hw(i); + break; + } + win_id = -1; + } + } + } + else if(event.window.event == SDL_WINDOWEVENT_MAXIMIZED) + { + Uint32 win_id = -1; + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(rc_win[i]) + { + win_id = SDL_GetWindowID(rc_win[i]); + if(win_id == event.window.windowID) + { + rc_win_event[i] = 3; + //rc_media_closeWindow_hw(i); + break; + } + win_id = -1; + } + } + } + break; + case SDL_TEXTINPUT: + if(rc_textinput_flag == true) + { + rc_textinput_string += event.text.text; + } + break; + case SDL_KEYUP: + break; + case SDL_KEYDOWN: + if(rc_textinput_isActive && event.key.keysym.sym == SDLK_BACKSPACE && rc_textinput_string.length() > 0 + && rc_toggleBackspace) + { + rc_textinput_string = rc_utf8_substr(rc_textinput_string, 0, rc_utf8_length(rc_textinput_string)-1); + } + + rc_inkey = event.key.keysym.sym; + break; + //case SDL_MOUSEMOTION: + //SDL_GetMouseState(&rc_mouseX, &rc_mouseY); + //break; + case SDL_MOUSEBUTTONUP: + //SDL_GetMouseState(&rc_mouseX, &rc_mouseY); + rc_mbutton1 = 0; + rc_mbutton2 = 0; + rc_mbutton3 = 0; + //break; + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + rc_mbutton1 = 0; + break; + case SDL_BUTTON_MIDDLE: + rc_mbutton2 = 0; + break; + case SDL_BUTTON_RIGHT: + rc_mbutton3 = 0; + break; + } + break; + case SDL_MOUSEBUTTONDOWN: + //SDL_GetMouseState(&rc_mouseX, &rc_mouseY); + //rc_mbutton1 = 0; + //rc_mbutton2 = 0; + //rc_mbutton3 = 0; + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + rc_mbutton1 = 1; + break; + case SDL_BUTTON_MIDDLE: + rc_mbutton2 = 1; + break; + case SDL_BUTTON_RIGHT: + rc_mbutton3 = 1; + break; + } + break; + case SDL_MOUSEWHEEL: + rc_mwheelx = event.wheel.x; + rc_mwheely = event.wheel.y; + break; +// case SDL_JOYBUTTONDOWN: +// rc_joybutton[event.jbutton.which][event.jbutton.button] = 1; +// break; +// case SDL_JOYBUTTONUP: +// rc_joybutton[event.jbutton.which][event.jbutton.button] = 0; +// break; +// case SDL_JOYAXISMOTION: +// rc_joy_axis[event.jaxis.which][event.jaxis.axis] = event.jaxis.value; +// break; + case SDL_JOYDEVICEREMOVED: + //cout << "Joystick Removed: Instance " << event.jdevice.which << endl; + for(int i = 0; i < 8; i++) + { + if(event.jdevice.which == rc_joyID[i] && rc_joystick[i]) + { + //cout << "Joystick [" << i << "] was removed" << endl; + SDL_HapticClose(rc_haptic[i]); + SDL_JoystickClose(rc_joystick[i]); + rc_joystick[i] = NULL; + rc_haptic[i] = NULL; + rc_joyID[i] = -1; + rc_numJoysticks--; + break; + } + } + break; + case SDL_JOYDEVICEADDED: + //cout << "Joystick Added: " << event.jdevice.which << endl; + tmp_joy = SDL_JoystickOpen(event.jdevice.which); + tmp_joy_id = SDL_JoystickInstanceID(tmp_joy); + tmp_joy_flag = 0; + + for(int i = 0; i < 8; i++) + { + if(tmp_joy_id == rc_joyID[i]) + { + tmp_joy_flag = 1; + break; + } + } + + if(event.jdevice.which >= 0 && tmp_joy_flag == 0) + { + for(int i = 0; i < 8; i++) + { + if(rc_joystick[i] == NULL) + { + //cout << "Assigned " << i << endl; + rc_joystick[i] = tmp_joy; + rc_haptic[i] = SDL_HapticOpenFromJoystick(rc_joystick[i]); + SDL_HapticRumbleInit(rc_haptic[i]); + rc_joyID[i] = tmp_joy_id; + rc_numJoysticks++; + break; + } + } + } + break; +#ifndef RC_MOBILE //This block handles touch events for non-mobile devices, Just in case it has a touch screen that SDL2 can get events for + case SDL_FINGERDOWN: + rc_touch = 1; + rc_touchX = event.tfinger.x * rc_win_width[rc_active_window]; + rc_touchY = event.tfinger.y * rc_win_height[rc_active_window]; +#ifdef RC_IOS + rc_pressure = 1; //FIXME: On IOS pressure is always getting reported as 0 on finger down so I am just setting it to 1 until I figure this out +#else + rc_pressure = event.tfinger.pressure; +#endif + rc_setTouchFingerEvent(event.tfinger.fingerId, rc_touchX, rc_touchY, rc_pressure); + break; + case SDL_FINGERUP: + rc_touch = 0; + rc_mt_status = 0; + rc_touchX = event.tfinger.x * rc_win_width[rc_active_window]; + rc_touchY = event.tfinger.y * rc_win_height[rc_active_window]; + rc_pressure = event.tfinger.pressure; + rc_setTouchFingerEvent(event.tfinger.fingerId, -1, -1, 0); + break; + case SDL_FINGERMOTION: + rc_touch = 1; + rc_touchX = event.tfinger.x * rc_win_width[rc_active_window]; + rc_touchY = event.tfinger.y * rc_win_height[rc_active_window]; + rc_motionX = event.tfinger.dx * rc_win_width[rc_active_window]; + rc_motionY = event.tfinger.dy * rc_win_height[rc_active_window]; +#ifdef RC_IOS + rc_pressure = 1; +#else + rc_pressure = event.tfinger.pressure; +#endif + rc_setTouchFingerEvent(event.tfinger.fingerId, rc_touchX, rc_touchY, rc_pressure); + break; + case SDL_MULTIGESTURE: + rc_touch = 2; + rc_mt_status = 1; + rc_mt_x = event.mgesture.x; + rc_mt_y = event.mgesture.y; + rc_mt_numFingers = event.mgesture.numFingers; + rc_mt_dist = event.mgesture.dDist; + rc_mt_theta = event.mgesture.dTheta; +#ifdef RC_IOS + rc_pressure = 1; +#else + rc_pressure = event.tfinger.pressure; +#endif + break; +#endif + } + //cout << "end_event" << endl; + return g_events; +} + +bool rc_media_windowEvent_Close(int win_num) +{ + if(rc_winCheck(win_num)) + { + if(rc_win_event[win_num]==1) + { + //cout << "Window #" << win_num << " Close_Event" << endl; + return true; + } + else + return false; + } + return false; +} + +bool rc_media_windowEvent_Minimize(int win_num) +{ + if(rc_winCheck(win_num)) + { + if(rc_win_event[win_num]==2) + return true; + else + return false; + } + return false; +} + +bool rc_media_windowEvent_Maximize(int win_num) +{ + if(rc_winCheck(win_num)) + { + if(rc_win_event[win_num]==3) + return true; + else + return false; + } + return false; +} + +bool rc_media_windowEvent_Resize(int win_num) +{ + if(rc_winCheck(win_num)) + { + if(rc_win_event[win_num]==4) + return true; + else + return false; + } + return false; +} + +void rc_media_windowEvent_setExitOnClose(int win_num, int exitOnClose) +{ + rc_win_exitOnClose[win_num] = (exitOnClose != 0) ? true : false; +} + +void rc_media_getTouchFinger(int finger, double * x, double * y, double * pressure) +{ + if(finger < MAX_FINGERS) + { + *x = rc_finger[finger].x; + *y = rc_finger[finger].y; + *pressure = rc_finger[finger].pressure; + } +} + +int rc_media_numFingers() +{ + return rc_fingers_pressed.size(); + //if(rc_touchDevice) + // return SDL_GetNumTouchFingers(rc_touchDevice); + //return 0; +} + +double rc_media_touchPressure() +{ + return rc_pressure; +} + +void rc_media_getTouch(double * status, double * x, double * y, double * distX, double * distY) +{ + *status = (double)rc_touch; + *x = (double)rc_touchX; + *y = (double)rc_touchY; + *distX = (double)rc_motionX; + *distY = (double)rc_motionY; + return; +} + +void rc_media_getMultiTouch(double * status, double * x, double * y, double * numFingers, double * dist, double * theta) +{ + *status = (double)rc_mt_status; + *x = (double)rc_mt_x; + *y = (double)rc_mt_y; + *numFingers = (double)rc_mt_numFingers; + *dist = rc_mt_dist; + *theta = rc_mt_theta; + return; +} + +void rc_media_getAccel(uint32_t accel_num, double * x, double * y, double * z) +{ + float sensor_data[4]; + if(accel_num < num_accels) + SDL_SensorGetData(rc_accel[accel_num], &sensor_data[0], 3); + *x = sensor_data[0]; + *y = sensor_data[1]; + *z = sensor_data[2]; +} + +string rc_media_accelName(uint32_t accel_num) +{ + if(accel_num < num_accels) + return (string)SDL_SensorGetName(rc_accel[accel_num]); + return ""; +} + +int rc_media_numAccels() +{ + return num_accels; +} + +void rc_media_getGyro(uint32_t gyro_num, double * x, double * y, double * z) +{ + float sensor_data[4]; + if(gyro_num < num_gyros) + SDL_SensorGetData(rc_gyro[gyro_num], &sensor_data[0], 3); + *x = sensor_data[0]; + *y = sensor_data[1]; + *z = sensor_data[2]; +} + +string rc_media_gyroName(uint32_t gyro_num) +{ + if(gyro_num < num_gyros) + return (string)SDL_SensorGetName(rc_gyro[gyro_num]); + return ""; +} + +int rc_media_numGyros() +{ + return num_gyros; +} + +void rc_media_ReadInput_Start() +{ + SDL_StartTextInput(); + rc_textinput_isActive = true; + rc_textinput_string = ""; + rc_textinput_timer = clock() / (double)(CLOCKS_PER_SEC / 1000); +} + +void rc_media_ReadInput_Stop() +{ + rc_textinput_isActive = false; + rc_textinput_timer = 0; + rc_textinput_string = ""; + SDL_StopTextInput(); +} + +string rc_media_ReadInput_Text() +{ + return rc_textinput_string; +} + +void rc_media_ReadInput_SetText(string txt) +{ + rc_textinput_string = txt; +} + +void rc_media_ReadInput_ToggleBackspace(bool flag) +{ + rc_toggleBackspace = flag; +} + +int rc_media_inkey() +{ + int k = rc_inkey; + return k; +} + +int rc_media_key(int check_Key) +{ + if(keyState == NULL) + keyState = SDL_GetKeyboardState(NULL); + return keyState[SDL_GetScancodeFromKey(check_Key)]; +} + +int rc_media_waitKey() +{ + bool wk_loop = true; + SDL_Event e; + while(wk_loop) + { + while(SDL_WaitEvent(&e)) + { + if(e.type == SDL_KEYDOWN) + return (int)e.key.keysym.sym; + } + } + return 0; +} + +void rc_media_wait(Uint32 ms) +{ + SDL_Delay(ms); +} + +void rc_media_hideMouse() +{ + SDL_ShowCursor(0); + rc_cursor_visible = 0; +} + +void rc_media_showMouse() +{ + SDL_ShowCursor(1); + rc_cursor_visible = 1; +} + +bool rc_media_mouseIsVisible() +{ + return rc_cursor_visible; +} + +int rc_media_mouseX() +{ + //SDL_GetMouseState(&rc_mouseX,&rc_mouseY); + //cout << "debug: " << rc_fullscreen_mouse_scale_x[rc_active_window] << endl; + #ifdef RC_MOBILE + return rc_mouseX; + #else + return rc_mouseX * rc_fullscreen_mouse_scale_x[rc_active_window]; + #endif // RC_MOBILE +} + +int rc_media_mouseY() +{ + //SDL_GetMouseState(&rc_mouseX,&rc_mouseY); + #ifdef RC_MOBILE + return rc_mouseY; + #else + return rc_mouseY * rc_fullscreen_mouse_scale_y[rc_active_window]; + #endif // RC_MOBILE +} + +int rc_media_mouseButton(int m) +{ + switch(m) + { + case 0: + return rc_mbutton1; + case 1: + return rc_mbutton2; + case 2: + return rc_mbutton3; + } + return -1; +} + +void rc_media_getMouse(double * x, double * y, double * mb1, double * mb2, double * mb3) +{ + //SDL_GetMouseState(&rc_mouseX,&rc_mouseY); + //SDL_PumpEvents(); + *mb1 = rc_mbutton1; + *mb2 = rc_mbutton2; + *mb3 = rc_mbutton3; + #ifdef RC_MOBILE + *x = rc_mouseX; + *y = rc_mouseY; + #else + *x = (int)(rc_mouseX * rc_fullscreen_mouse_scale_x[rc_active_window]); + *y = (int)(rc_mouseY * rc_fullscreen_mouse_scale_y[rc_active_window]); + //cout << "debug getMouse = " << rc_mouseX << " * " << rc_fullscreen_mouse_scale_x[rc_active_window] << endl; + #endif // RC_MOBILE + return; +} + +int rc_media_globalMouseX() +{ + //SDL_GetGlobalMouseState(&rc_mouseX,&rc_mouseY); + return rc_global_mouseX; +} + +int rc_media_globalMouseY() +{ + //SDL_GetGlobalMouseState(&rc_mouseX,&rc_mouseY); + return rc_global_mouseY; +} + +void rc_media_getGlobalMouse(double * x, double * y, double * mb1, double * mb2, double * mb3) +{ + //SDL_GetGlobalMouseState(&rc_mouseX,&rc_mouseY); + //SDL_PumpEvents(); + *mb1 = rc_mbutton1; + *mb2 = rc_mbutton2; + *mb3 = rc_mbutton3; + *x = rc_global_mouseX; + *y = rc_global_mouseY; + return; +} + +int rc_media_mouseWheelX() +{ + return rc_mwheelx; +} + +int rc_media_mouseWheelY() +{ + return rc_mwheely; +} + +void rc_media_getMouseWheel(double * x_axis, double * y_axis) +{ + *x_axis = rc_mwheelx; + *y_axis = rc_mwheely; + return; +} + +void rc_media_grabInput(bool flag) +{ + SDL_SetWindowGrab(rc_win[rc_active_window], flag ? SDL_TRUE : SDL_FALSE); +} + +int rc_media_grabbedWindow() +{ + for(int i = 0; i < MAX_WINDOWS; i++) + { + if(SDL_GetWindowGrab(rc_win[i])) + return i; + } + return -1; +} + +void rc_media_warpMouse(int x, int y) +{ + SDL_WarpMouseInWindow(rc_win[rc_active_window], x, y); +} + +void rc_media_warpMouseGlobal(int x, int y) +{ + SDL_WarpMouseGlobal(x, y); +} + +void rc_media_setMouseZone(int x, int y, int w, int h) +{ + SDL_Rect r; + r.x = x; + r.y = y; + r.w = w; + r.h = h; + SDL_SetWindowMouseRect(rc_win[rc_active_window], &r); +} + +void rc_media_clearMouseZone() +{ + SDL_SetWindowMouseRect(rc_win[rc_active_window], NULL); +} + +void rc_media_setWindowAlwaysOnTop(int win, bool flag) +{ + if(win < 0 || win >= MAX_WINDOWS) + return; + SDL_SetWindowAlwaysOnTop(rc_win[win], flag ? SDL_TRUE : SDL_FALSE); +} + +void rc_media_setMouseRelative(bool flag) +{ + SDL_SetRelativeMouseMode(flag ? SDL_TRUE : SDL_FALSE); +} + +void rc_media_setWindowVSync(int win, bool flag) +{ + SDL_RenderSetVSync(rc_win_renderer[win], flag ? SDL_TRUE : SDL_FALSE); +} + +int rc_media_openURL(string url) +{ + return SDL_OpenURL(url.c_str()); +} + +string rc_media_APIVersion() +{ + SDL_version version; + SDL_GetVersion(&version); + + stringstream ss; + ss << (uint32_t)version.major << "." << (uint32_t)version.minor << "." << (uint32_t)version.patch; + return ss.str(); + +} + +int rc_media_flashWindow(int win) +{ + //SDL_FlashOperation op; + return SDL_FlashWindow(rc_win[win], SDL_FLASH_UNTIL_FOCUSED); +} + +int rc_media_messageBox(string title, string msg) +{ + return SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, title.c_str(), msg.c_str(), NULL); +} + +void rc_media_updateWindow_hw() +{ + if(!rc_win[rc_active_window]) + return; + int s_num = 0; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_backBuffer[rc_active_window]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_clearColor >> 16, rc_clearColor >> 8, rc_clearColor, 255); + //SDL_RenderFillRect(rc_win_renderer[rc_active_window], NULL); + SDL_RenderClear(rc_win_renderer[rc_active_window]); + for(int i = MAX_SCREENS-1; i >= 0; i--) + { + s_num = rc_screen_zOrder[rc_active_window][i]; + //cout << "DRAW SCREEN: " << s_num << endl; + if(rc_hscreen[rc_active_window][s_num] != NULL && rc_screen_visible[rc_active_window][s_num]) + { + //cout << "draw canvas " << s_num << endl; + #ifdef RC_WEB + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][s_num], &rc_screenview[rc_active_window][s_num], &rc_screen_rect[rc_active_window][s_num]); + #else + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][s_num], &rc_screenview[rc_active_window][s_num], &rc_screen_rect[rc_active_window][s_num]); + #endif + } + } + //#ifndef RC_ANDROID + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_hconsole[rc_active_window], NULL, NULL); + //#endif // RC_ANDROID + //cout << endl; + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], NULL); + #if defined(RC_MOBILE) || defined(RC_WEB) + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_backBuffer[rc_active_window], NULL, NULL); + #else + SDL_RenderCopy(rc_win_renderer[rc_active_window], rc_backBuffer[rc_active_window], &rc_bb_rect[rc_active_window], NULL); + #endif // RC_ANDROID + SDL_RenderPresent(rc_win_renderer[rc_active_window]); + SDL_SetRenderTarget(rc_win_renderer[rc_active_window], rc_hscreen[rc_active_window][rc_active_screen]); + SDL_SetRenderDrawColor(rc_win_renderer[rc_active_window], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + rc_fps_frames[rc_active_window]++; + + uint32_t t = SDL_GetTicks(); + + if( (t - rc_fps_timer[rc_active_window]) >= 1000 ) + { + rc_fps_timer[rc_active_window] = t; + rc_fps[rc_active_window] = rc_fps_frames[rc_active_window]; + rc_fps_frames[rc_active_window] = 0; + } +} + +void rc_media_updateAllWindow_hw() +{ + for(int win_num = 0; win_num < MAX_WINDOWS; win_num++) + { + if(!rc_win[win_num]) + continue; + int s_num = 0; + SDL_SetRenderTarget(rc_win_renderer[win_num], rc_backBuffer[win_num]); + SDL_SetRenderDrawColor(rc_win_renderer[win_num], rc_clearColor >> 16, rc_clearColor >> 8, rc_clearColor, 255); + //SDL_RenderFillRect(rc_win_renderer[win_num], NULL); + SDL_RenderClear(rc_win_renderer[win_num]); + for(int i = MAX_SCREENS-1; i >= 0; i--) + { + s_num = rc_screen_zOrder[win_num][i]; + //cout << "DRAW SCREEN: " << s_num << endl; + if(rc_hscreen[win_num][s_num] != NULL && rc_screen_visible[win_num][s_num]) + { + //cout << "draw canvas " << s_num << endl; + #ifdef RC_WEB + SDL_RenderCopy(rc_win_renderer[win_num], rc_hscreen[win_num][s_num], &rc_screenview[win_num][s_num], &rc_screen_rect[win_num][s_num]); + #else + SDL_RenderCopy(rc_win_renderer[win_num], rc_hscreen[win_num][s_num], &rc_screenview[win_num][s_num], &rc_screen_rect[win_num][s_num]); + #endif + } + } + //#ifndef RC_ANDROID + SDL_RenderCopy(rc_win_renderer[win_num], rc_hconsole[win_num], NULL, NULL); + //#endif // RC_ANDROID + //cout << endl; + SDL_SetRenderTarget(rc_win_renderer[win_num], NULL); + #if defined(RC_MOBILE) || defined(RC_WEB) + SDL_RenderCopy(rc_win_renderer[win_num], rc_backBuffer[win_num], NULL, NULL); + #else + SDL_RenderCopy(rc_win_renderer[win_num], rc_backBuffer[win_num], &rc_bb_rect[win_num], NULL); + #endif // RC_ANDROID + SDL_RenderPresent(rc_win_renderer[win_num]); + SDL_SetRenderTarget(rc_win_renderer[win_num], rc_hscreen[win_num][rc_active_screen]); + SDL_SetRenderDrawColor(rc_win_renderer[win_num], rc_ink_color.r, rc_ink_color.g, rc_ink_color.b, rc_ink_color.a); + + rc_fps_frames[win_num]++; + + uint32_t t = SDL_GetTicks(); + + if( (t - rc_fps_timer[win_num]) >= 1000 ) + { + rc_fps_timer[win_num] = t; + rc_fps[win_num] = rc_fps_frames[win_num]; + rc_fps_frames[win_num] = 0; + } + } +} + +bool rc_media_imageExist_hw(int slot) +{ + return rc_image_isLoaded[slot]; +} + +int rc_media_numJoysticks() +{ + return SDL_NumJoysticks(); +} + +int rc_media_joyAxis(int joy_num, int axis) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickGetAxis(rc_joystick[joy_num], axis); + return 0; +} + +int rc_media_joyButton(int joy_num, int jbutton) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickGetButton(rc_joystick[joy_num], jbutton); + return 0; +} + +string rc_media_joystickName(int joy_num) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return (string)SDL_JoystickName(rc_joystick[joy_num]); + return ""; +} + +int rc_media_numJoyButtons(int joy_num) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickNumButtons(rc_joystick[joy_num]); + return 0; +} + +int rc_media_numJoyAxes(int joy_num) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickNumAxes(rc_joystick[joy_num]); + return 0; +} + +int rc_media_numJoyHats(int joy_num) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickNumHats(rc_joystick[joy_num]); + return 0; +} + +int rc_media_joyHat(int joy_num, int hat) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickGetHat(rc_joystick[joy_num], hat); + return 0; +} + +int rc_media_numJoyTrackBalls(int joy_num) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + return SDL_JoystickNumBalls(rc_joystick[joy_num]); + return 0; +} + +void rc_media_getJoyTrackBall(int joy_num, int ball, double * dx, double * dy) +{ + int x = 0; + int y = 0; + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + SDL_JoystickGetBall(rc_joystick[joy_num], ball, &x, &y); + *dx = x; + *dy = y; +} + +bool rc_media_joystickIsConnected( int joy_num ) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + { + if(rc_joystick[joy_num]) + return true; + return false; + } + return false; +} + +void rc_media_joyRumblePlay(int joy_num, double strength, double duration) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + { + SDL_HapticRumblePlay(rc_haptic[joy_num], strength, (Uint32)duration); + } +} + +void rc_media_joyRumbleStop(int joy_num) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + SDL_HapticRumbleStop(rc_haptic[joy_num]); +} + +int rc_media_joystickIsHaptic( int joy_num ) +{ + if(joy_num >= 0 && joy_num < MAX_JOYSTICKS) + { + if(rc_haptic[joy_num]) + return 1; + } + return 0; +} + +int rc_media_queryAudioSpec(double * freq, double * format, double * channels) +{ + //need to do something here + int qa_freq = 0; + Uint16 qa_format = 0; + int qa_channels = 0; + int result = Mix_QuerySpec(&qa_freq, &qa_format, &qa_channels); + *freq = (double)qa_freq; + *format = (double)qa_format; + *channels = (double)qa_channels; + return result; +} + +void rc_media_loadSound(int slot, string fname) +{ + if(rc_sound[slot] != NULL) + { + Mix_FreeChunk(rc_sound[slot]); + } + rc_sound[slot] = Mix_LoadWAV(fname.c_str()); + if(rc_sound[slot] == NULL) + { + cout << "Could not load sound: " << Mix_GetError() << endl; + return; + } +} + +void rc_media_createSound(int slot, double * abuf, Uint32 alen, Uint8 volume) +{ + if(!rc_sound[slot]) + { + rc_sound[slot] = (Mix_Chunk*)SDL_malloc(sizeof(Mix_Chunk)); + //cout << "sound dbg 0" << endl; + rc_sound[slot]->allocated = 1; + //cout << "GOOD START" << endl; + rc_sound[slot]->abuf = (Uint8*)SDL_malloc(sizeof(Uint8)*alen); + //cout << "sound dbg 1" << endl; + for(int i = 0; i < alen; i++) + rc_sound[slot]->abuf[i] = (Uint8)abuf[i]; + //cout << "sound dbg 2" << endl; + rc_sound[slot]->alen = alen; + rc_sound[slot]->volume = volume; + } +} + +void rc_media_loadMusic(string fname) +{ + if(rc_music != NULL) + { + Mix_FreeMusic(rc_music); + } + rc_music = Mix_LoadMUS(fname.c_str()); + if(rc_music == NULL) + { + cout << "Could not load music: " << Mix_GetError() << endl; + return; + } +} + +void rc_media_deleteMusic() +{ + if(rc_music) + { + Mix_FreeMusic(rc_music); + rc_music = NULL; + } +} + +void rc_media_playSound(int slot, int channel, int loops) +{ + if(rc_sound[slot] != NULL) + { + Mix_PlayChannel(channel, rc_sound[slot], loops); + } +} + +void rc_media_playSoundTimed(int slot, int channel, int loops, int ms) +{ + if(rc_sound[slot] != NULL) + { + Mix_PlayChannelTimed(channel, rc_sound[slot], loops, ms); + } +} + +void rc_media_playMusic(int loops) +{ + if(rc_music != NULL) + { + Mix_PlayMusic(rc_music, loops); + } +} + +int rc_media_musicIsPlaying() +{ + if(rc_music != NULL) + { + return Mix_PlayingMusic(); + } + return 0; +} + +void rc_media_pauseSound(int channel) +{ + if(Mix_Playing(channel)) + { + Mix_Pause(channel); + } +} + +void rc_media_resumeSound(int channel) +{ + if(!Mix_Playing(channel)) + { + Mix_Resume(channel); + } +} + +void rc_media_pauseMusic() +{ + if(Mix_PlayingMusic()) + { + Mix_PauseMusic(); + } +} + +void rc_media_resumeMusic() +{ + if(!Mix_PlayingMusic()) + { + Mix_ResumeMusic(); + } +} + +void rc_media_deleteSound(int slot) +{ + if(rc_sound[slot] != NULL) + { + Mix_FreeChunk(rc_sound[slot]); + rc_sound[slot] = NULL; + } +} + +void rc_media_fadeMusicIn(int time, int loops) +{ + Mix_FadeInMusic(rc_music, loops, time); +} + +void rc_media_fadeMusicOut(int time) +{ + Mix_FadeOutMusic(time); +} + +bool rc_media_musicExists() +{ + if(rc_music != NULL) + return true; + return false; +} + +void rc_media_setMusicVolume(int volume) +{ + Mix_VolumeMusic(volume); +} + +int rc_media_getMusicVolume() +{ + return Mix_VolumeMusic(-1); +} + +void rc_media_setMusicPosition(double position) +{ + Mix_SetMusicPosition(position); +} + +double rc_media_getMusicPosition() +{ + return Mix_SetMusicPosition(-1); +} + +void rc_media_rewindMusic() +{ + Mix_RewindMusic(); +} + +void rc_media_setSoundChannels(int max_channels) +{ + Mix_AllocateChannels(max_channels); +} + +int rc_media_getSoundChannels() +{ + return Mix_AllocateChannels(-1); +} + +bool rc_media_soundIsEnabled() +{ + return (bool) Mix_Init(0); +} + +bool rc_media_soundExists(int slot) +{ + if(rc_sound[slot] != NULL) + return true; + return false; +} + +void rc_media_setChannelVolume(int channel, int volume) +{ + Mix_Volume(channel, volume); +} + +int rc_media_getChannelVolume(int channel) +{ + return Mix_Volume(channel, -1); +} + +void rc_media_setSoundVolume(int slot, int volume) +{ + Mix_VolumeChunk(rc_sound[slot], volume); +} + +int rc_media_getSoundVolume(int slot) +{ + return Mix_VolumeChunk(rc_sound[slot], -1); +} + +void rc_media_stopMusic() +{ + Mix_HaltMusic(); +} + +void rc_media_stopSound(int channel) +{ + Mix_HaltChannel(channel); +} + +int rc_media_channelIsPlaying(int channel) +{ + return Mix_Playing(channel); +} + +int rc_media_channelIsPaused(int channel) +{ + return Mix_Paused(channel); +} + +int rc_media_setChannelDistance(int channel, Uint8 dist) +{ + return Mix_SetDistance(channel, dist); +} + +int rc_media_setChannelPanning(int channel, Uint8 l, Uint8 r) +{ + return Mix_SetPanning(channel, l, r); +} + + +int rc_media_setChannelSpacePosition(int channel, double angle, double distance) +{ + return Mix_SetPosition(channel, (Sint16)angle, (Uint8) distance); +} + + +//NETWORKING + +//TCPsocket rc_socket[5]; +//UDPsocket rc_udp_socket[5]; +//UDPpacket * rc_udp_packet; +//int rc_udp_channel; +//string rc_udp_data; +//int rc_udp_len; +//int rc_udp_maxlen; +//string rc_udp_host; +//Uint16 rc_udp_port; + +int rc_net_tcp_openSocket(int _socket, string host, Uint16 port) +{ + if(_socket >= MAX_SOCKETS) + { + cout << "TCP_SocketOpen Error: Maximum number of sockets available is " << MAX_SOCKETS << endl; + return 0; + } + IPaddress ip; + if(host.compare("") == 0) + { + //exit(0); + SDLNet_ResolveHost(&ip, NULL, port); + } + else + { + //exit(0); + SDLNet_ResolveHost(&ip, host.c_str(), port); + } + rc_socket[_socket] = SDLNet_TCP_Open(&ip); + if(rc_socket[_socket]) + { + //cout << "Add socket to socket_set" << endl; + SDLNet_TCP_AddSocket(rc_socket_set, rc_socket[_socket]); + return 1; + } + return 0; +} + +void rc_net_tcp_closeSocket(int _socket) +{ + if( _socket >= MAX_SOCKETS) + { + cout << "TCP_SocketClose Error: Maximum number of sockets available is " << MAX_SOCKETS << endl; + return; + } + SDLNet_TCP_DelSocket(rc_socket_set, rc_socket[_socket]); + SDLNet_TCP_Close(rc_socket[_socket]); + rc_socket[_socket] = NULL; +} + +Uint32 rc_net_tcp_remoteHost(int _socket) +{ + IPaddress * ip = SDLNet_TCP_GetPeerAddress(rc_socket[_socket]); + return ip->host; +} + +Uint32 rc_net_tcp_remotePort(int _socket) +{ + IPaddress * ip = SDLNet_TCP_GetPeerAddress(rc_socket[_socket]); + return ip->port; +} + +int rc_net_checkSockets(Uint32 m) +{ + return SDLNet_CheckSockets(rc_socket_set, m); +} + +int rc_net_tcp_socketReady(int _socket) +{ + return SDLNet_SocketReady(rc_socket[_socket]); +} + +int rc_net_tcp_getData(int socket, void * dst, int numBytes) +{ + int rtn = SDLNet_TCP_Recv(rc_socket[socket], dst, numBytes); + return rtn; +} + +int rc_net_tcp_getData_str(int socket, string * dst, int numBytes) +{ + char c[numBytes+1]; + int rtn = rc_net_tcp_getData(socket, c, numBytes); + c[numBytes] = '\0'; + //cout << "Read bytes: " << (string)c << endl; + dst[0] = c; + return rtn; +} + +int rc_net_tcp_getData_dbl(int socket, double * dst, int numBytes) +{ + int i[numBytes]; + int rtn = rc_net_tcp_getData(socket, i, numBytes); + for(int n = 0; n < numBytes; n++) + { + dst[n] = i[n]; + } + return rtn; +} + +void rc_net_tcp_sendData(int socket, const char * data, int numBytes) +{ + SDLNet_TCP_Send(rc_socket[socket], data, numBytes); +} + +bool rc_net_tcp_acceptSocket(int socket_server, int socket_client) +{ + //cout << "\n\nthis is a test\n\n"; + if(rc_socket[socket_server] == NULL) + { + //cout << "no server" << endl; + return false; + } + bool val = (rc_socket[socket_client] = SDLNet_TCP_Accept(rc_socket[socket_server])); + if(val) + SDLNet_TCP_AddSocket(rc_socket_set, rc_socket[socket_client]); + //cout << "cp1\n"; + return val; +} + +bool rc_net_udp_openSocket(int socket, Uint16 port) +{ + bool rtn = (bool)(rc_udp_socket[socket] = SDLNet_UDP_Open(port)); + if(rtn) + SDLNet_UDP_AddSocket(rc_socket_set, rc_udp_socket[socket]); + return rtn; +} + +int rc_net_udp_socketReady(int socket) +{ + return SDLNet_SocketReady(rc_udp_socket[socket]); +} + +int rc_net_udp_readStream(int socket, string * dst, string * host, double * port) +{ + //cout << "DEBUG READSTREAM\n"; + //UDPsocket sd; /* Socket descriptor */ + //UDPpacket *p; /* Pointer to packet memory */ + //int quit = 0; + + /* Make space for the packet */ + //if (!(rc_udp_packet = SDLNet_AllocPacket(512))) + //{ + // fprintf(stderr, "SDLNet_AllocPacket: %s\n", SDLNet_GetError()); + // exit(EXIT_FAILURE); + //} + + /* Main loop */ + + /* Wait a packet. UDP_Recv returns != 0 if a packet is coming */ + //while(!quit) + //{ + if (SDLNet_UDP_Recv(rc_udp_socket[socket], rc_udp_packet)) + { + //printf("UDP Packet incoming\n"); + //printf("\tChan: %d\n", rc_udp_packet->channel); + rc_udp_channel = rc_udp_packet->channel; + //printf("\tData: %s\n", (char *)rc_udp_packet->data); + const char * c = (const char *)rc_udp_packet->data; + //rc_udp_data = (string)c; + *dst = (string)c; + //printf("\tLen: %d\n", rc_udp_packet->len); + rc_udp_len = rc_udp_packet->len; + //printf("\tMaxlen: %d\n", rc_udp_packet->maxlen); + rc_udp_maxlen = rc_udp_packet->maxlen; + //printf("\tStatus: %d\n", rc_udp_packet->status); + //printf("\tAddress: %x %x\n", rc_udp_packet->address.host, rc_udp_packet->address.port); + //rc_udp_host = SDLNet_ResolveIP(&rc_udp_packet->address); + *host = SDLNet_ResolveIP(&rc_udp_packet->address); + //rc_udp_port = rc_udp_packet->address.port; + *port = rc_udp_packet->address.port; + return 1; + //quit = 1; + } + else + { + rc_udp_channel = 0; + //rc_udp_data = ""; + *dst = ""; + rc_udp_len = 0; + rc_udp_maxlen = rc_udp_packet->maxlen; + //rc_udp_host = SDLNet_ResolveIP(&rc_udp_packet->address); + *host = SDLNet_ResolveIP(&rc_udp_packet->address); + //rc_udp_port = rc_udp_packet->address.port; + *port = rc_udp_packet->address.port; + return 0; + } + + //} + + //SDLNet_FreePacket(rc_udp_packet); +} + +Uint32 rc_net_udp_len() +{ + return rc_udp_len; +} + +Uint32 rc_net_udp_maxlen() +{ + return rc_udp_maxlen; +} + +string rc_net_udp_getRemoteHost(int socket) +{ + IPaddress * ip = SDLNet_UDP_GetPeerAddress(rc_udp_socket[socket],0); + // + return SDLNet_ResolveIP(ip); +} + +Uint32 rc_net_udp_getRemotePort(int socket) +{ + IPaddress * ip = SDLNet_UDP_GetPeerAddress(rc_udp_socket[socket],0); + return ip->port; +} + +int rc_net_udp_closeSocket(int socket) +{ + SDLNet_UDP_DelSocket(rc_socket_set, rc_udp_socket[socket]); + SDLNet_UDP_Close(rc_udp_socket[socket]); + rc_udp_socket[socket] = NULL; + return 0; +} + +int rc_net_udp_sendData(int slot, string host, Uint16 port, string s_data) +{ + IPaddress srvadd; + + if(s_data.length()+1 > rc_packet_size) + { + rc_packet_size = SDLNet_ResizePacket(rc_udp_packet, s_data.length()+1); + if(rc_packet_size < s_data.length()) + { + cout << "UDP_SendData Error: " << SDLNet_GetError() << endl; + return 0; + } + } + + + if(rc_udp_packet == NULL) + return 0; + + + if (SDLNet_ResolveHost(&srvadd, host.c_str(), port) == -1) + { + std::cout << "UDP_SendData Error: " << SDLNet_GetError() << "\n"; + //exit(EXIT_FAILURE); + return 0; + } + + rc_udp_packet->address.host = srvadd.host; + rc_udp_packet->address.port = srvadd.port; + rc_udp_packet->data = (Uint8*)s_data.c_str(); + + + rc_udp_packet->len = s_data.length()+1; + //cout << "#Data = " << (char*)rc_udp_packet->data << endl; + //cout << "#Length = " << rc_udp_packet->len << endl; + SDLNet_UDP_Send(rc_udp_socket[slot], -1, rc_udp_packet); + + return 1; +} + +string rc_byteToString(Uint8 n) +{ + stringstream s; + s << (Uint32)n; + return s.str(); +} + +string rc_net_myLocalIP() +{ + //cout << "MYLOCALIP" << endl; + IPaddress myIP; + myIP.host = 0; + myIP.port = 0; + string net_name = SDLNet_ResolveIP(&myIP); + SDLNet_ResolveHost(&myIP,net_name.c_str(),0); + string ip = ""; + ip += rc_byteToString((Uint8)myIP.host) + "."; + ip += rc_byteToString((Uint8)(myIP.host >> 8)) + "."; + ip += rc_byteToString((Uint8)(myIP.host >> 16)) + "."; + ip += rc_byteToString((Uint8)(myIP.host >> 24)); + //cout << "vagina: " << myIP.host << endl; + return ip; +} + +//#################VIDEO PLAYBACK##################################################################### + +#ifdef RC_USE_TREMOR +void videoPlayer_audio_callback(void *userdata, Uint8 *stream, int len) +{ + // !!! FIXME: this should refuse to play if item->playms is in the future. + //const Uint32 now = SDL_GetTicks() - baseticks; + Sint16 *dst = (Sint16 *) stream; + + while (audio_queue && (len > 0)) + { + volatile AudioQueue *item = audio_queue; + AudioQueue *next = item->next; + const int channels = item->audio->channels; + + const Sint32 *src = (Sint32 *) (item->audio->samples + (item->offset * channels)); + + int cpy = (item->audio->frames - item->offset) * channels; + int i; + + if (cpy > (len / sizeof (Sint16))) + cpy = len / sizeof (Sint16); + + for (i = 0; i < cpy; i++) + { + const Sint32 val = *(src++); + + if (val < -32768) + *(dst++) = -32768; + else if (val > 32767) + *(dst++) = 32767; + else + { + *(dst++) = (Sint16) (val); + } + } // for + + item->offset += (cpy / channels); + len -= cpy * sizeof (Sint16); + + if (item->offset >= item->audio->frames) + { + THEORAPLAY_freeAudio(item->audio); + free((void *) item); + audio_queue = next; + } // if + } // while + + if (!audio_queue) + audio_queue_tail = NULL; + + if (len > 0) + memset(dst, '\0', len); +} // audio_callback +#else +void videoPlayer_audio_callback(void *userdata, Uint8 *stream, int len) +{ + // !!! FIXME: this should refuse to play if item->playms is in the future. + //const Uint32 now = SDL_GetTicks() - baseticks; + Sint16 *dst = (Sint16 *) stream; + + while (audio_queue && (len > 0)) + { + volatile AudioQueue *item = audio_queue; + AudioQueue *next = item->next; + const int channels = item->audio->channels; + + const float *src = item->audio->samples + (item->offset * channels); + int cpy = (item->audio->frames - item->offset) * channels; + int i; + + if (cpy > (len / sizeof (Sint16))) + cpy = len / sizeof (Sint16); + + for (i = 0; i < cpy; i++) + { + const float val = *(src++); + if (val < -1.0f) + *(dst++) = -32768; + else if (val > 1.0f) + *(dst++) = 32767; + else + *(dst++) = (Sint16) (val * 32767.0f); + } // for + + item->offset += (cpy / channels); + len -= cpy * sizeof (Sint16); + + if (item->offset >= item->audio->frames) + { + THEORAPLAY_freeAudio(item->audio); + free((void *) item); + audio_queue = next; + } // if + } // while + + if (!audio_queue) + audio_queue_tail = NULL; + + if (len > 0) + memset(dst, '\0', len); +} // audio_callback +#endif + +static void videoPlayer_queue_audio(const THEORAPLAY_AudioPacket *audio) +{ + AudioQueue *item = (AudioQueue *) malloc(sizeof (AudioQueue)); + if (!item) + { + THEORAPLAY_freeAudio(audio); + return; // oh well. + } // if + + item->audio = audio; + item->offset = 0; + item->next = NULL; + + //SDL_LockAudio(); + if (audio_queue_tail) + audio_queue_tail->next = item; + else + audio_queue = item; + audio_queue_tail = item; + //SDL_UnlockAudio(); +} // queue_audio + +void rc_media_loadVideo(string fname) +{ + //cout << "CRAP" << endl; + decoder = THEORAPLAY_startDecodeFile(fname.c_str(), 30, THEORAPLAY_VIDFMT_RGBA); + if(!decoder) + { + decoder = NULL; + cout << "Failed to load video: " << fname << endl; + return; + } + + rc_video_file = fname; + while (!audio || !video) + { + if (!audio) audio = THEORAPLAY_getAudio(decoder); + if (!video) video = THEORAPLAY_getVideo(decoder); + SDL_Delay(10); + } // if + overlay = SDL_CreateTexture(rc_win_renderer[rc_active_window], SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, video->width, video->height); + SDL_SetTextureBlendMode(overlay, SDL_BLENDMODE_BLEND); + SDL_SetTextureAlphaMod(overlay, 255); + framems = (video->fps == 0.0) ? 0 : ((Uint32) (1000.0 / video->fps)); + rc_video_dstrect.x = 0; + rc_video_dstrect.y = 0; + rc_video_dstrect.w = video->width; + rc_video_dstrect.h = video->height; + rc_video_width = video->width; + rc_video_height = video->height; + + if (!overlay) + { + fprintf(stderr, "Video failed: %s\n", SDL_GetError()); + return; + } + //} // else + + initfailed = quit = (!overlay); + rc_video_end = false; + + + //fprintf(stderr, "b_debug 3.5\n"); +} + +int rc_media_getVideoStats(string fname, double * v_len, double * v_fps, double * v_width, double * v_height) +{ + //cout << "CRAP" << endl; + if(decoder) + return 0; + decoder = THEORAPLAY_startDecodeFile(fname.c_str(), 30, THEORAPLAY_VIDFMT_RGBA); + if(!decoder) + { + decoder = NULL; + cout << "Failed to load video: " << fname << endl; + return 0; + } + + while(THEORAPLAY_isDecoding(decoder)) + { + if(!video) + video = THEORAPLAY_getVideo(decoder); + if(video) + { + rc_video_length = video->playms; + rc_video_fps = video->fps; + rc_video_width = video->width; + rc_video_height = video->height; + THEORAPLAY_freeVideo(video); + video = NULL; + } + + if(!audio) + audio = THEORAPLAY_getAudio(decoder); + if(audio) + { + THEORAPLAY_freeAudio(audio); + audio = NULL; + } + + //SDL_Delay(1); + } + + THEORAPLAY_stopDecode(decoder); + decoder = NULL; + + *v_len = rc_video_length; + *v_fps = rc_video_fps; + *v_width = rc_video_width; + *v_height = rc_video_height; + rc_video_length = 0; + rc_video_fps = 0; + rc_video_width = 0; + rc_video_height = 0; + return 1; +} + +void rc_media_getVideoSize(double * w, double * h) +{ + *w = rc_video_width; + *h = rc_video_height; +} + +void rc_media_setVideoDrawRect(int x, int y, int w, int h) +{ + rc_video_dstrect.x = x; + rc_video_dstrect.y = y; + rc_video_dstrect.w = w; + rc_video_dstrect.h = h; +} + +void rc_media_getVideoDrawRect(double * x, double * y, double * w, double * h) +{ + *x = rc_video_dstrect.x; + *y = rc_video_dstrect.y; + *w = rc_video_dstrect.w; + *h = rc_video_dstrect.h; +} + +int rc_media_videoLength() +{ + return rc_video_length; +} + +void rc_cleanResume() +{ + //cout << "tat" << endl; + //if (overlay) SDL_DestroyTexture(overlay); + if (video) THEORAPLAY_freeVideo(video); + if (audio) THEORAPLAY_freeAudio(audio); + if (decoder) THEORAPLAY_stopDecode(decoder); + //cout << "bubble wrap" << endl; + //SDL_ClearQueuedAudio(0); + //while(SDL_GetQueuedAudioSize(0)>0){} + + rc_video_isPlaying = false; + video = NULL; + audio = NULL; + decoder = NULL; + decoder = THEORAPLAY_startDecodeFile(rc_video_file.c_str(), 30, THEORAPLAY_VIDFMT_RGBA); + while(!audio && !video && THEORAPLAY_isDecoding(decoder)) + { + audio = THEORAPLAY_getAudio(decoder); + video = THEORAPLAY_getVideo(decoder); + if(audio) + { + if(audio->playms <= rc_video_pauseTicks) + { + THEORAPLAY_freeAudio(audio); + audio = NULL; + } + } + + if(video) + { + if(video->playms <= rc_video_pauseTicks) + { + THEORAPLAY_freeVideo(video); + video = NULL; + } + } + } + //cout << "bankai" << endl; +} + +void rc_media_playVideo(int loops) +{ + if(rc_video_isPlaying) + return; + if(rc_video_reset) + { + //cout << "RESET" << endl; + decoder = THEORAPLAY_startDecodeFile(rc_video_file.c_str(), 30, THEORAPLAY_VIDFMT_RGBA); + if(!decoder) + { + cout << "Video Reset Error: " << SDL_GetError() << endl; + } + while(!audio || !video) + { + if(!audio) audio = THEORAPLAY_getAudio(decoder); + if(!video) video = THEORAPLAY_getVideo(decoder); + SDL_Delay(10); + } + rc_video_reset = false; + } + + Mix_CloseAudio(); + rc_video_currentLoop = 0; + rc_video_loops = loops; + rc_video_isPlaying = true; + + if(Mix_OpenAudio(audio->freq, AUDIO_S16SYS, audio->channels, 2048) < 0) + { + rc_audio_isOpen = false; + cout << "Open Audio Error: " << Mix_GetError() <0){} + SDL_Delay(1500); + if(rc_audio_isOpen) + { + Mix_CloseAudio(); + if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 2048) < 0) + { + cout << "OpenAudio Error: " << Mix_GetError() << endl; + } + Mix_HookMusic(NULL, NULL); + rc_audio_isOpen = false; + } + rc_video_isPlaying = false; + rc_video_loops = 0; + rc_video_currentLoop = 0; + rc_video_position = 0; + rc_video_reset = true; + rc_video_end = false; + video = NULL; + audio = NULL; + decoder = NULL; + //cout << "mini" << endl; +} + +static bool cycleVideo() +{ + //cout << "video_start" << endl; + if(!rc_video_isPlaying) + return false; + //cout << "never print this" << endl; + //int q = !quit; + //int tp = THEORAPLAY_isDecoding(decoder); + //cout << "VARS = " << q << " & " << tp << endl; + int isDecode = THEORAPLAY_isDecoding(decoder); + if(isDecode) + rc_video_end = false; + else + { + rc_video_currentLoop++; + if((rc_video_currentLoop <= rc_video_loops) || (rc_video_loops < 0)) + { + rc_media_stopVideo(); + rc_media_playVideo(rc_video_loops); + return true; + } + rc_video_end = true; + rc_video_isPlaying = false; + } + + if (!quit && isDecode) + { + const Uint32 now = SDL_GetTicks() - baseticks; + rc_video_pauseTicks = now; + rc_video_position = now; + + if (!video) + video = THEORAPLAY_getVideo(decoder); + + //fprintf(stderr, "b_debug A\n"); + + // Play video frames when it's time. + if (video && (video->playms <= now)) + { + //fprintf(stderr, "b_debug B\n"); + //printf("Play video frame (%u ms)!\n", video->playms); + if ( framems && ((now - video->playms) >= framems) ) + { + //fprintf(stderr, "b_debug C\n"); + // Skip frames to catch up, but keep track of the last one + // in case we catch up to a series of dupe frames, which + // means we'd have to draw that final frame and then wait for + // more. + const THEORAPLAY_VideoFrame *last = video; + while ((video = THEORAPLAY_getVideo(decoder)) != NULL) + { + THEORAPLAY_freeVideo(last); + last = video; + if ((now - video->playms) < framems) + break; + } // while + + //fprintf(stderr, "b_debug D\n"); + + if (!video) + video = last; + } // if + + //fprintf(stderr, "b_debug B.1\n"); + int lock_tex = SDL_LockTexture(overlay, NULL, &overlay_pixels, &pitch); + //fprintf(stderr, "b_debug B.1.2\n"); + + if (!video) // do nothing; we're far behind and out of options. + { + static int warned = 0; + if (!warned) + { + warned = 1; + fprintf(stderr, "WARNING: Playback can't keep up!\n"); + } // if + } // if + else if (lock_tex<0) + { + //fprintf(stderr, "b_debug E\n"); + static int warned = 0; + if (!warned) + { + warned = 1; + fprintf(stderr, "Couldn't lock video frame: %s\n", SDL_GetError()); + } // if + } // else if + else + { + //fprintf(stderr, "b_debug 4\n"); + //SDL_Rect dstrec = { 0, 0, video->width, video->height }; + const int w = video->width; + const int h = video->height; + Uint8 *dst; + + const Uint8 * vbuf = (const Uint8*)video->pixels; + + dst = (Uint8*)overlay_pixels; + + SDL_memcpy(dst, vbuf, w*h*4); + + //fprintf(stderr, "b_debug 7\n"); + + SDL_UnlockTexture(overlay); + + //if (SDL_DisplayYUVOverlay(overlay, &dstrect) != 0) + if(SDL_RenderCopy(rc_win_renderer[rc_active_window], overlay, NULL, &rc_video_dstrect) < 0) + { + static int warned = 0; + if (!warned) + { + warned = 1; + fprintf(stderr, "Couldn't display video frame: %s\n", SDL_GetError()); + } // if + } // if + else + { + //SDL_RenderPresent(rc_win_renderer[rc_active_window]); + //cout << "window drawn" << endl; + } + } // else + //fprintf(stderr, "b_debug B.5\n"); + + THEORAPLAY_freeVideo(video); + video = NULL; + } // if + else // no new video frame? Give up some CPU. + { + SDL_Delay(10); + } // else + + //fprintf(stderr, "b_debug F\n"); + while ((audio = THEORAPLAY_getAudio(decoder)) != NULL) + videoPlayer_queue_audio(audio); + + return true; + } // while + return false; + +} // playfile + +void rc_media_deleteVideo() +{ + //cout << "cream soda" << endl; + if (overlay) SDL_DestroyTexture(overlay); + overlay = NULL; + if (video) THEORAPLAY_freeVideo(video); + video = NULL; + if (audio) THEORAPLAY_freeAudio(audio); + audio = NULL; + if (decoder) THEORAPLAY_stopDecode(decoder); + decoder = NULL; + //cout << "bubble wrap" << endl; + if(rc_audio_isOpen) + { + Mix_CloseAudio(); + if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 2048) < 0) + { + cout << "OpenAudio Error: " << Mix_GetError() << endl; + } + rc_audio_isOpen = false; + Mix_HookMusic(NULL, NULL); + } + rc_video_file = ""; + rc_video_isLoaded = false; + rc_video_isPlaying = false; + rc_video_loops = 0; + rc_video_position = 0; + rc_video_length = 0; + rc_video_width = 0; + rc_video_height = 0; + rc_video_dstrect.x = 0; + rc_video_dstrect.y = 0; + rc_video_dstrect.w = 0; + rc_video_dstrect.h = 0; + //cout << "mini" << endl; +} + +void rc_media_pauseVideo() +{ + //if(rc_video_isPaused) + // return; + rc_video_isPlaying = false; + if (video) THEORAPLAY_freeVideo(video); + if (audio) THEORAPLAY_freeAudio(audio); + Mix_Pause(-1); + SDL_Delay(1500); + if(rc_audio_isOpen) + { + Mix_CloseAudio(); + if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 2048) < 0) + { + cout << "OpenAudio Error: " << Mix_GetError() << endl; + } + rc_audio_isOpen = false; + } + video = NULL; + audio = NULL; + rc_video_isPaused = true; +} + +void rc_media_resumeVideo() +{ + if(!rc_video_isPaused) + return; + + //fprintf(stderr, "RESUME\n" ); + + int dec_cycle = 0; + + while(!audio || !video) + { + if(!audio) audio = THEORAPLAY_getAudio(decoder); + if(!video) video = THEORAPLAY_getVideo(decoder); + SDL_Delay(10); + dec_cycle++; + if(dec_cycle == 100) + rc_cleanResume(); + if(dec_cycle >= 200) + { + rc_video_isPaused = false; + rc_media_stopVideo(); + return; + } + //fprintf(stderr,"working\n"); + } + + //fprintf(stderr,"debug 1\n"); + if(!rc_audio_isOpen) + Mix_CloseAudio(); + rc_video_isPlaying = true; + //fprintf(stderr,"debug 2\n"); + + if(!rc_audio_isOpen) + { + if(Mix_OpenAudio(audio->freq, AUDIO_S16SYS, audio->channels, 2048) < 0) + { + cout << "Open Audio Error: " << Mix_GetError() < +#ifdef RC_ANDROID + #include "SDL.h" +#else + #include +#endif +#include +#include "rc_matrix.h" +#include "rc_defines.h" + +#define MAX_SUBPROCESS 3 + +#define RC_THREAD_ONERROR_CONTINUE 0 +#define RC_THREAD_ONERROR_STOP 1 + +SDL_Thread* rc_subprocess_thread[3]; + +struct rc_threadData +{ + uint32_t sub_process_num; +}; + +rc_threadData rc_subprocess_param[3]; + +struct rc_subprocess_mutex_container +{ + SDL_mutex* queue_mutex; + SDL_mutex* current_op_mutex; + SDL_mutex* error_mode_mutex; + bool queue_mutex_locked; + bool current_op_mutex_locked; + bool error_mode_mutex_locked; +}; + +rc_subprocess_mutex_container rc_subprocess_mutex[3]; + + +struct rc_process_op +{ + int fn; + double n[10]; + // I will add a string arg whenever a string op gets implemented +}; + +struct rc_process_op_list +{ + queue op; +}; + +rc_process_op_list rc_subprocess_queue[3]; + +uint32_t rc_subprocess_error_mode[3]; +int rc_subprocess_error[3]; + +int rc_active_matrix_process = -1; + +void rc_initSubprocessSystem() +{ + for(int i = 0; i < MAX_SUBPROCESS; i++) + { + rc_subprocess_thread[i] = NULL; + rc_subprocess_mutex[i].current_op_mutex = SDL_CreateMutex(); + rc_subprocess_mutex[i].error_mode_mutex = SDL_CreateMutex(); + rc_subprocess_mutex[i].queue_mutex = SDL_CreateMutex(); + rc_subprocess_mutex[i].current_op_mutex_locked = false; + rc_subprocess_mutex[i].error_mode_mutex_locked = false; + rc_subprocess_mutex[i].queue_mutex_locked = false; + } +} + +#define RC_QUEUE_MUTEX 1 +#define RC_ERROR_MODE_MUTEX 2 +#define RC_CURRENT_OP_MUTEX 3 + +void rc_lockMutex(int process_num, uint32_t m) +{ + switch(m) + { + case RC_QUEUE_MUTEX: + if(!rc_subprocess_mutex[process_num].queue_mutex_locked) + SDL_LockMutex(rc_subprocess_mutex[process_num].queue_mutex); + rc_subprocess_mutex[process_num].queue_mutex_locked = true; + break; + + case RC_ERROR_MODE_MUTEX: + if(!rc_subprocess_mutex[process_num].error_mode_mutex_locked) + SDL_LockMutex(rc_subprocess_mutex[process_num].error_mode_mutex); + rc_subprocess_mutex[process_num].error_mode_mutex_locked = true; + break; + + case RC_CURRENT_OP_MUTEX: + if(!rc_subprocess_mutex[process_num].current_op_mutex_locked) + SDL_LockMutex(rc_subprocess_mutex[process_num].current_op_mutex); + rc_subprocess_mutex[process_num].current_op_mutex_locked = true; + break; + } +} + +void rc_unlockMutex(int process_num, uint32_t m) +{ + switch(m) + { + case RC_QUEUE_MUTEX: + rc_subprocess_mutex[process_num].queue_mutex_locked = false; + SDL_UnlockMutex(rc_subprocess_mutex[process_num].queue_mutex); + break; + + case RC_ERROR_MODE_MUTEX: + rc_subprocess_mutex[process_num].error_mode_mutex_locked = false; + SDL_UnlockMutex(rc_subprocess_mutex[process_num].error_mode_mutex); + break; + + case RC_CURRENT_OP_MUTEX: + rc_subprocess_mutex[process_num].current_op_mutex_locked = false; + SDL_UnlockMutex(rc_subprocess_mutex[process_num].current_op_mutex); + break; + } +} + +int rc_subprocess_fn( void* data) +{ + rc_threadData* param = (rc_threadData*) data; + + int process_num = param->sub_process_num; + + //std::cout << "thread start " << process_num << std::endl; + + rc_process_op op; + bool p_loop = true; + + while(p_loop) + { + op.fn = -1; + rc_lockMutex(process_num, RC_QUEUE_MUTEX); + if(rc_subprocess_queue[process_num].op.size() > 0) + { + op = rc_subprocess_queue[process_num].op.front(); + rc_unlockMutex(process_num, RC_QUEUE_MUTEX); + } + else + rc_unlockMutex(process_num, RC_QUEUE_MUTEX); + + rc_lockMutex(process_num, RC_CURRENT_OP_MUTEX); + rc_lockMutex(process_num, RC_ERROR_MODE_MUTEX); + + switch(op.fn) + { + case 0: + p_loop = false; //std::cout << "THREAD_END_OP " << std::endl; + break; + + case FN_DimMatrix: //Sub Procedure + DimMatrix(op.n[0], op.n[1], op.n[2], op.n[3]); + break; + case FN_AddMatrix: //Number Function + rc_subprocess_error[process_num] = (AddMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_AugmentMatrix: //Number Function + rc_subprocess_error[process_num] = (AugmentMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_CopyMatrix: //Sub Procedure + CopyMatrix(op.n[0], op.n[1]); + break; + case FN_InsertMatrixColumns: //Number Function + rc_subprocess_error[process_num] = (InsertMatrixColumn(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_InsertMatrixRows: //Number Function + rc_subprocess_error[process_num] = (InsertMatrixRow(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_MultiplyMatrix: //Number Function + rc_subprocess_error[process_num] = (MultiplyMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_CubeMatrix: //Number Function + rc_subprocess_error[process_num] = (CubeMatrix(op.n[0], op.n[1], process_num)) ? 0 : op.fn; + break; + case FN_DeleteMatrixColumns: //Number Function + rc_subprocess_error[process_num] = (DeleteMatrixColumns(op.n[0], op.n[1], op.n[2], process_num)) ? 0 : op.fn; + break; + case FN_DeleteMatrixRows: //Number Function + rc_subprocess_error[process_num] = (DeleteMatrixRows(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_ClearMatrix: //Sub Procedure + ClearMatrix(op.n[0]); + break; + case FN_ClearMatrixColumns: //Number Function + rc_subprocess_error[process_num] = (ClearMatrixColumns(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_ClearMatrixRows: //Number Function + rc_subprocess_error[process_num] = (ClearMatrixRows(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; + break; + case FN_FillMatrix: //Sub Procedure + FillMatrix(op.n[0], op.n[1]); + break; + case FN_FillMatrixColumns: //Number Function + rc_subprocess_error[process_num] = (FillMatrixColumns(op.n[0], op.n[1], op.n[2], op.n[3])) ? 0 : op.fn; + break; + case FN_FillMatrixRows: //Number Function + rc_subprocess_error[process_num] = (FillMatrixRows(op.n[0], op.n[1], op.n[2], op.n[3])) ? 0 : op.fn; + break; + case FN_CopyMatrixColumns: //Number Function + rc_subprocess_error[process_num] = (GetMatrixColumns(op.n[0], op.n[1], op.n[2], op.n[3])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_CopyMatrixRows: //Number Function + rc_subprocess_error[process_num] = (GetMatrixRows(op.n[0], op.n[1], op.n[2], op.n[3])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_IdentityMatrix: //Sub Procedure + IdentityMatrix(op.n[0], op.n[1]); + break; + case FN_SolveMatrix: //Number Function + rc_subprocess_error[process_num] = (SolveMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_IsEqualMatrix: //Number Function + rc_subprocess_error[process_num] = (IsEqualMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_AdjointMatrix: //Number Function + rc_subprocess_error[process_num] = (AdjointMatrix(op.n[0], op.n[1])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_InvertMatrix: //Number Function + rc_subprocess_error[process_num] = (InvertMatrix(op.n[0], op.n[1])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_RandomizeMatrix: //Sub Procedure + RandomizeMatrix(op.n[0], op.n[1], op.n[2]); + break; + case FN_SetMatrixValue: //Sub Procedure + SetMatrixValue(op.n[0], op.n[1], op.n[2], op.n[3]); + break; + case FN_ScalarMatrix: //Sub Procedure + ScalarMatrix(op.n[0], op.n[1], op.n[2]); + break; + case FN_ScalarMatrixColumns: //Number Function + rc_subprocess_error[process_num] = (ScalarMatrixColumns(op.n[0], op.n[1], op.n[2], op.n[3], op.n[4])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_ScalarMatrixRows: //Number Function + rc_subprocess_error[process_num] = (ScalarMatrixRows(op.n[0], op.n[1], op.n[2], op.n[3], op.n[4])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_SquareMatrix: //Number Function + rc_subprocess_error[process_num] = (SquareMatrix(op.n[0], op.n[1])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_SubMatrix: //Sub Procedure + SubMatrix(op.n[0], op.n[1], op.n[2]); + break; + case FN_SubtractMatrix: //Number Function + rc_subprocess_error[process_num] = (SubtractMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_SwapMatrix: //Sub Procedure + SwapMatrix(op.n[0], op.n[1], process_num); // 1 needs to be replaced with error code + break; + case FN_SwapMatrixColumn: //Number Function + rc_subprocess_error[process_num] = (SwapMatrixColumn(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_SwapMatrixRow: //Number Function + rc_subprocess_error[process_num] = (SwapMatrixRow(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_TransposeMatrix: //Number Function + rc_subprocess_error[process_num] = (TransposeMatrix(op.n[0], op.n[1])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_UnAugmentMatrix: //Number Function + rc_subprocess_error[process_num] = (UnAugmentMatrix(op.n[0], op.n[1], op.n[2])) ? 0 : op.fn; // 1 needs to be replaced with error code + break; + case FN_ZeroMatrix: //Sub Procedure + ZeroMatrix(op.n[0]); + break; + case FN_ProcessSleep: //Sub Procedure + SDL_Delay(op.n[0]); + break; + + } + + if(op.fn >= 0) + { + rc_lockMutex(process_num, RC_QUEUE_MUTEX); + if(rc_subprocess_queue[process_num].op.size()>0) + rc_subprocess_queue[process_num].op.pop(); + rc_unlockMutex(process_num, RC_QUEUE_MUTEX); + } + + if(rc_subprocess_error[process_num] != 0) + { + switch(rc_subprocess_error_mode[process_num]) + { + case RC_THREAD_ONERROR_CONTINUE: + rc_unlockMutex(process_num, RC_ERROR_MODE_MUTEX); + break; + case RC_THREAD_ONERROR_STOP: + rc_unlockMutex(process_num, RC_ERROR_MODE_MUTEX); + bool error_status = true; + while(error_status) + { + rc_lockMutex(process_num, RC_ERROR_MODE_MUTEX); + error_status = (rc_subprocess_error[process_num] != 0); + rc_unlockMutex(process_num, RC_ERROR_MODE_MUTEX); + //std::cout << "THREAD_ERROR " << error_status << std::endl; + SDL_Delay(5); + } + break; + } + } + else + rc_unlockMutex(process_num, RC_ERROR_MODE_MUTEX); + + rc_unlockMutex(process_num, RC_CURRENT_OP_MUTEX); + + } + + //std::cout << "thread end " << process_num << std::endl; + + return 0; + +} + + +bool rc_setMatrixProcess(int p_num) +{ + if(p_num >= 0 && p_num < MAX_SUBPROCESS) + rc_active_matrix_process = p_num; + else + rc_active_matrix_process = -1; + + if(rc_active_matrix_process >= 0) + return (rc_subprocess_thread[rc_active_matrix_process] != NULL); + + return true; //main process is set +} + +bool rc_processOpen(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return false; + + if(rc_subprocess_thread[p_num]) + return false; + + for(int i = 0; i < rc_subprocess_queue[p_num].op.size(); i++) + rc_subprocess_queue[p_num].op.pop(); + + rc_subprocess_thread[p_num] = SDL_CreateThread(rc_subprocess_fn, "rc_subprocess", &rc_subprocess_param[0]); + + return (rc_subprocess_thread[p_num] != NULL); +} + +void rc_setProcessErrorMode(int p_num, uint32_t error_mode) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return; + + if(error_mode < 0 || error_mode > 1) + error_mode = 0; + + rc_lockMutex(p_num, RC_ERROR_MODE_MUTEX); + rc_subprocess_error_mode[p_num] = error_mode; + rc_unlockMutex(p_num, RC_ERROR_MODE_MUTEX); +} + +int ProcessError(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return 0; + + rc_lockMutex(p_num, RC_ERROR_MODE_MUTEX); + int error = rc_subprocess_error[p_num]; + rc_unlockMutex(p_num, RC_ERROR_MODE_MUTEX); + + return error; +} + +void ProcessWait(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return; + + if(!rc_subprocess_thread[p_num]) + return; + + //std::cout << "q_LOCK " << std::endl; + rc_lockMutex(p_num, RC_QUEUE_MUTEX); + uint32_t q_size = rc_subprocess_queue[p_num].op.size(); + rc_unlockMutex(p_num, RC_QUEUE_MUTEX); + + //std::cout << "q_size = " << q_size << std::endl; + + while(q_size > 0) + { + rc_lockMutex(p_num, RC_QUEUE_MUTEX); + q_size = rc_subprocess_queue[p_num].op.size(); + rc_unlockMutex(p_num, RC_QUEUE_MUTEX); + } + +} + +void ProcessWaitAll() +{ + for(uint32_t i = 0; i < MAX_SUBPROCESS; i++) + ProcessWait(i); +} + +void ProcessContinue(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return; + + rc_lockMutex(p_num, RC_ERROR_MODE_MUTEX); + rc_subprocess_error[p_num] = 0; + rc_unlockMutex(p_num, RC_ERROR_MODE_MUTEX); + + rc_unlockMutex(p_num, RC_CURRENT_OP_MUTEX); +} + +void ProcessContinueAll() +{ + for(uint32_t i = 0; i < MAX_SUBPROCESS; i++) + ProcessContinue(i); +} + +void ProcessStop(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return; + + rc_lockMutex(p_num, RC_CURRENT_OP_MUTEX); +} + +void ProcessStopAll() +{ + for(uint32_t i = 0; i < MAX_SUBPROCESS; i++) + ProcessStop(i); +} + +void ProcessClear(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return; + + rc_lockMutex(p_num, RC_QUEUE_MUTEX); + uint32_t q_size = rc_subprocess_queue[p_num].op.size(); + + for(uint32_t i = 0; i < q_size; i++) + rc_subprocess_queue[p_num].op.pop(); + + rc_unlockMutex(p_num, RC_QUEUE_MUTEX); + + rc_lockMutex(p_num, RC_ERROR_MODE_MUTEX); + rc_subprocess_error[p_num] = 0; + rc_unlockMutex(p_num, RC_ERROR_MODE_MUTEX); +} + +bool ProcessClose(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return false; + + if(!rc_subprocess_thread[p_num]) + return false; + + rc_process_op op; + op.fn = 0; + + ProcessClear(p_num); + + rc_lockMutex(p_num, RC_QUEUE_MUTEX); + rc_subprocess_queue[p_num].op.push(op); + rc_unlockMutex(p_num, RC_QUEUE_MUTEX); + + SDL_WaitThread(rc_subprocess_thread[p_num], NULL); + + rc_subprocess_thread[p_num] = NULL; + + if(rc_active_matrix_process == p_num) + rc_active_matrix_process = -1; + + return true; +} + +uint32_t ProcessErrorMode(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return 0; + + rc_lockMutex(p_num, RC_ERROR_MODE_MUTEX); + uint32_t error_mode = rc_subprocess_error_mode[p_num]; + rc_unlockMutex(p_num, RC_ERROR_MODE_MUTEX); + return error_mode; +} + +void ProcessSleep(int p_num, uint32_t msec) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return; + + rc_process_op op; + op.fn = FN_ProcessSleep; + op.n[0] = msec; + + rc_lockMutex(p_num, RC_QUEUE_MUTEX); + rc_subprocess_queue[p_num].op.push(op); + rc_unlockMutex(p_num, RC_QUEUE_MUTEX); +} + +bool ProcessExists(int p_num) +{ + if(p_num < 0 || p_num >= MAX_SUBPROCESS) + return false; + + return (rc_subprocess_thread[p_num] != NULL); +} + +uint32_t ProcessQueueSize(int p_num) +{ + rc_lockMutex(p_num, RC_QUEUE_MUTEX); + int q_size = rc_subprocess_queue[p_num].op.size(); + rc_unlockMutex(p_num, RC_QUEUE_MUTEX); + + return q_size; +} + +void ProcessQueueMatrixOp(uint32_t fn, double n0 = 0, double n1 = 0, double n2 = 0, double n3 = 0, double n4 = 0, double n5 = 0, + double n6 = 0, double n7 = 0, double n8 = 0, double n9 = 0) +{ + rc_process_op op; + op.fn = fn; + op.n[0] = n0; + op.n[1] = n1; + op.n[2] = n2; + op.n[3] = n3; + op.n[4] = n4; + op.n[5] = n5; + op.n[6] = n6; + op.n[7] = n7; + op.n[8] = n8; + op.n[9] = n9; + + rc_lockMutex(rc_active_matrix_process, RC_QUEUE_MUTEX); + rc_subprocess_queue[rc_active_matrix_process].op.push(op); + rc_unlockMutex(rc_active_matrix_process, RC_QUEUE_MUTEX); +} + +void rc_cleanSubprocessSystem() +{ + for(int i = 0; i < MAX_SUBPROCESS; i++) + { + ProcessClose(i); + SDL_DestroyMutex(rc_subprocess_mutex[i].current_op_mutex); + SDL_DestroyMutex(rc_subprocess_mutex[i].error_mode_mutex); + SDL_DestroyMutex(rc_subprocess_mutex[i].queue_mutex); + } +} + +int NumCPUs() +{ + return SDL_GetCPUCount(); +} + +#endif // RC_PROCESS_H_INCLUDED diff --git a/rcbasic_runtime/rc_stdlib.h b/rcbasic_runtime/rc_stdlib.h new file mode 100644 index 0000000..7fedb54 --- /dev/null +++ b/rcbasic_runtime/rc_stdlib.h @@ -0,0 +1,1556 @@ +#ifndef RC_STDLIB_H_INCLUDED +#define RC_STDLIB_H_INCLUDED + +#include "rc_os_defines.h" + +#define RC_PI 3.14159265359 + +#ifdef RC_MAC +#define RC_GETCWD +#include +#endif + +#ifdef RC_ANDROID +#define RC_GETCWD +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //file system stuff +#include //file system stuff +#include //file system stuff +#include +#include +#include +#include + +#ifdef RC_ANDROID + #include "SDL.h" + #include +#else + #include +#endif +// + + +#ifdef RC_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#endif // RC_WINDOWS + +using namespace std; + +#define RC_MAX_FILES 32 + +#define RC_FILE_IO_TEXT_INPUT 1 +#define RC_FILE_IO_TEXT_OUTPUT 2 +#define RC_FILE_IO_TEXT_APPEND 3 +#define RC_FILE_IO_TEXT_INPUT_UPDATE 4 +#define RC_FILE_IO_TEXT_OUTPUT_UPDATE 5 +#define RC_FILE_IO_TEXT_APPEND_UPDATE 6 +#define RC_FILE_IO_BINARY_INPUT 7 +#define RC_FILE_IO_BINARY_OUTPUT 8 +#define RC_FILE_IO_BINARY_APPEND 9 +#define RC_FILE_IO_BINARY_INPUT_UPDATE 10 +#define RC_FILE_IO_BINARY_OUTPUT_UPDATE 11 +#define RC_FILE_IO_BINARY_APPEND_UPDATE 12 + +#ifndef RC_WINDOWS + +struct dirent *rc_entry; +DIR *rc_dir; +string rc_dir_path = ""; + +#else + +struct dirent *rc_entry; +string rc_dir; +string rc_dir_path = ""; +HANDLE hfind; + +#endif // RC_LINUX + + +int rc_cmd_count = 0; +string * rc_cmd_args; + + +SDL_RWops * rc_fstream[RC_MAX_FILES]; +bool rc_eof[RC_MAX_FILES]; + +#define MAX_USER_STACKS 16 +int rc_user_active_n_stack = 0; +int rc_user_active_s_stack = 0; + +stack rc_user_n_stack[MAX_USER_STACKS]; +stack rc_user_s_stack[MAX_USER_STACKS]; + +#ifdef RC_WINDOWS +#define MAX_INPUT_LENGTH 32767 + +wchar_t wstr[MAX_INPUT_LENGTH]; +char mb_str[MAX_INPUT_LENGTH * 3 + 1]; + +#endif // RC_WINDOWS + + +std::string utf8_substr(const std::string& str, unsigned int start, unsigned int leng) +{ + if (leng==0) { return ""; } + unsigned int c, i, ix, q, min=std::string::npos, max=std::string::npos; + for (q=0, i=0, ix=str.length(); i < ix; i++, q++) + { + if (q==start){ min=i; } + if (q<=start+leng || leng==std::string::npos){ max=i; } + + c = (unsigned char) str[i]; + if ( + //c>=0 && + c<=127) i+=0; + else if ((c & 0xE0) == 0xC0) i+=1; + else if ((c & 0xF0) == 0xE0) i+=2; + else if ((c & 0xF8) == 0xF0) i+=3; + //else if (($c & 0xFC) == 0xF8) i+=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8 + //else if (($c & 0xFE) == 0xFC) i+=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8 + else return "";//invalid utf8 + } + if (q<=start+leng || leng==std::string::npos){ max=i; } + if (min==std::string::npos || max==std::string::npos) { return ""; } + return str.substr(min,max-min); +} + +std::size_t utf8_length(std::string const &s) +{ + return std::count_if(s.begin(), s.end(), + [](char c) { return (static_cast(c) & 0xC0) != 0x80; } ); +} + + +void rc_fprint(string txt) +{ + cout << txt; +} + +string rc_input(string prompt) +{ + #ifdef RC_WINDOWS + + string line = ""; + cout << prompt; + + unsigned long read; + void *con = GetStdHandle(STD_INPUT_HANDLE); + + ReadConsoleW(con, wstr, MAX_INPUT_LENGTH, &read, NULL); + + int s_size = WideCharToMultiByte(CP_UTF8, 0, wstr, read, mb_str, sizeof(mb_str), NULL, NULL); + mb_str[s_size] = 0; + + if(s_size >= 2) + { + if(mb_str[s_size-2]==10 || mb_str[s_size-2]==13) + mb_str[s_size-2] = 0; + + if(mb_str[s_size-1]==10 || mb_str[s_size-1]==13) + mb_str[s_size-1] = 0; + } + + return (string) mb_str; + + #else + + string line = ""; + cout << prompt; + getline(cin, line); + return line; + + #endif // RC_WINDOWS +} + +std::u32string to_utf32(const std::string &s) +{ + std::wstring_convert, char32_t> conv; + return conv.from_bytes(s); +} + +inline int rc_intern_asc(string c) +{ + return (uint32_t)to_utf32(utf8_substr(c, 0, 1))[0]; +} + +inline size_t rc_intern_bufferFromString(string s, double* buffer) +{ + for(int i = 0; i < s.length(); i++) + { + buffer[i] = (double)((uint32_t)s[i]); + } + return s.length(); +} + +std::string cpToUTF8(uint32_t cp) +{ + char utf8[4]; + int len = 0; + + if (cp <= 0x007F) + { + utf8[0] = static_cast(cp); + len = 1; + } + else + { + if (cp <= 0x07FF) + { + utf8[0] = 0xC0; + len = 2; + } + else if (cp <= 0xFFFF) + { + utf8[0] = 0xE0; + len = 3; + } + else if (cp <= 0x10FFFF) + { + utf8[0] = 0xF0; + len = 4; + } + else + throw std::invalid_argument("invalid codepoint"); + + for(int i = 1; i < len; ++i) + { + utf8[len-i] = static_cast(0x80 | (cp & 0x3F)); + cp >>= 6; + } + + utf8[0] |= static_cast(cp); + } + + return std::string(utf8, len); +} + +inline string rc_intern_chr(uint32_t n) +{ + string s = cpToUTF8(n); + //s += (char) n; + return s; +} + +inline string rc_intern_insert(string src, string tgt, size_t pos) +{ + if(pos < 0 || pos > utf8_length(src)) + return src; + + return utf8_substr(src, 0, pos) + tgt + utf8_substr(src, pos, utf8_length(src)-pos); +} + +inline double rc_intern_instr(string in_string, string in_substring) +{ + //cout << "Cant find " << rc_sid[INSTR_SUBSTR][0] << " in " << rc_sid[INSTR_STR][0] << endl; + bool found = false; + size_t n = 0;//(int)in_string.find(in_substring); + size_t search_len = utf8_length(in_string) - utf8_length(in_substring); + size_t sub_len = utf8_length(in_substring); + for(size_t i = 0; i <= search_len; i++) + { + if(utf8_substr(in_string, i, sub_len).compare(in_substring)==0) + { + n = i; + found = true; + break; + } + } + return found ? (double)n : -1; +} + +inline string rc_intern_lcase(string u_string) +{ + string u_string_out = ""; + for(size_t i=0;i= utf8_length(l_string)) + return l_string; + //cout << "DEBUG -> n = " << n << " : NPOS = " << string::npos << endl; + return utf8_substr(l_string,0,n); +} + +inline size_t rc_intern_length(string l_string) +{ + //cout << "DBG_LEN" << endl; + return utf8_length(l_string); +} + +inline string rc_intern_ltrim(string l_string) +{ + size_t first_index = l_string.find_first_not_of(" "); + if(first_index != string::npos) + return l_string.substr(first_index); + return l_string; +} + +inline string rc_intern_mid(string m_string, size_t m_start, size_t n) +{ + //cout << "DBG_MID" << endl; + if(m_start < 0 || n < 0) + return ""; + size_t m_string_length = utf8_length(m_string); + if(m_string_length <= m_start) + return ""; + if( (m_start+n) >= m_string_length) + return utf8_substr(m_string, m_start, m_string_length-m_start); + return utf8_substr(m_string, m_start, n); +} + +inline string rc_intern_replaceSubstr(string src, string rpc, size_t pos) +{ + size_t rpc_i = 0; + string n_str = utf8_substr(src, 0, pos); + + if(pos < 0) + return src; + + for(size_t i = pos; i < utf8_length(src); i++) + { + if(rpc_i < utf8_length(rpc)) + n_str += utf8_substr(rpc,rpc_i,1); + else + break; + rpc_i++; + } + if((pos+rpc_i) < utf8_length(src) ) + n_str += utf8_substr(src, pos+rpc_i, utf8_length(src)-(pos+rpc_i)); + return n_str; +} + +inline string rc_intern_replace(string src, string tgt, string rpc) +{ + if(tgt.length()==0) + return src; + size_t found_inc = rpc.length() > 0 ? rpc.length() : 1; + size_t found = 0; + found = src.find(tgt); + while( found != string::npos && found < src.length()) + { + src = src.substr(0,found) + rpc + src.substr(found + tgt.length()); + found = src.find(tgt,found+found_inc); + } + return src; +} + +inline string rc_intern_reverse(string rpc_string) +{ + string n_str = ""; + if(rpc_string.length()==0) + return ""; + + for(size_t i = utf8_length(rpc_string)-1;; i--) + { + n_str += utf8_substr(rpc_string, i, 1); + if(i==0) + break; + } + return n_str; +} + +inline string rc_intern_right(string src, size_t n) +{ + size_t src_length = utf8_length(src); + if(n < 0) + return ""; + if(n >= src_length) + return src; + return utf8_substr(src,src_length-n, src_length -(src_length-n)); +} + +inline string rc_intern_rtrim(string src) +{ + if(src.length()==0) + return ""; + + size_t i = 0; + for(i = utf8_length(src)-1; ; i--) + { + if(utf8_substr(src,i,1).compare(" ") != 0 || i == 0) + break; + } + if(i < 0) + return ""; + + return utf8_substr(src,0,i+1); +} + +inline size_t rc_intern_size(string src) +{ + return src.length(); +} + +inline string rc_intern_stringFromBuffer(double* buffer, size_t buffer_size) +{ + if(buffer_size <= 0) + return ""; + + char c_buf[buffer_size+1]; + + for(int i = 0; i < buffer_size; i++) + { + c_buf[i] = (uint8_t)buffer[i]; + } + + c_buf[buffer_size] = '\0'; + return (string)c_buf; +} + +inline string rc_intern_stringfill(string f_string, size_t n) +{ + string f = ""; + for(size_t i = 0; i < n; i++) + f += f_string; + return f; +} + +inline string rc_intern_str(double n) +{ + stringstream ss; + ss << n; + return ss.str(); +} + +inline string rc_intern_str_f(double n) +{ + stringstream ss; + ss << fixed << n; + return ss.str(); +} + +inline string rc_intern_str_s(double n) +{ + stringstream ss; + ss << scientific << n; + return ss.str(); +} + +inline unsigned long rc_intern_tally(string t_string, string t_substring) +{ + size_t found = 0; + string t_str = t_string; + string t_substr = t_substring; + found = t_str.find(t_substr); + unsigned long tally_count = 0; + while( found != string::npos) + { + tally_count++; + found = t_str.find(t_substr,found+1); + } + return tally_count; +} + +inline string rc_intern_trim(string t_string) +{ + return rc_intern_ltrim(rc_intern_rtrim(t_string)); +} + +inline string rc_intern_ucase(string u_string) +{ + string u_string_out = ""; + for(size_t i=0;i>= 1; + } + return binstr; +} + +inline string rc_intern_bin(uint64_t n) +{ + //string bin_str = bitset<64>(n).to_string(); + //bin_str = bin_str.substr(bin_str.find_first_not_of("0")); + string binstr = Convert(n);// bin_str; + return binstr.substr(binstr.find_first_not_of("0")); +} +#else + +inline string rc_intern_bin(uint64_t n) +{ + string bin_str = bitset<64>(n).to_string(); + bin_str = bin_str.substr(bin_str.find_first_not_of("0")); + return bin_str; +} + +#endif // RC_ANDROID + +union rc_cint_u +{ + int64_t i64; + int32_t i32[2]; +}; +double rc_intern_cint64(double n) +{ + rc_cint_u num; + num.i32[0] = (int32_t)n; + //cout << "dbg: " << num.i64 << endl; + return num.i64; +} + +double rc_intern_cint32(double n) +{ + rc_cint_u num; + num.i64 = (int64_t)n; + //cout << "dbg1: " << num.i32[0] << endl; + //cout << "dbg2: " << num.i32[1] << endl; + return num.i32[0]; +} + +inline double rc_intern_cos(double angle) +{ + return cos(angle); +} + +inline double rc_intern_exp(double n) +{ + return exp(n); +} + +inline double rc_intern_frac(double n) +{ + return n - floor(n); +} + +inline string rc_intern_hex(uint64_t n) +{ + stringstream ss; + ss << hex << n; + return ss.str(); +} + +inline double rc_intern_hexInt(string n) +{ + uint64_t x; + stringstream ss; + ss << hex << n; + ss >> x; + return (double)x; +} + +inline int64_t rc_intern_int(double n) +{ + return (int64_t)n; +} + +inline double rc_intern_log(double n) +{ + return log(n); +} + +inline double rc_intern_max(double a, double b) +{ + if(a > b) + return a; + else + return b; +} + +inline double rc_intern_min(double a, double b) +{ + if(a < b) + return a; + else + return b; +} + +inline double rc_intern_orBit(uint64_t a, uint64_t b) +{ + return (a | b); +} + +inline double rc_intern_radians(double degrees) +{ + return degrees * (RC_PI/180); +} + +inline double rc_intern_degrees(double radians) +{ + return radians * (180/RC_PI); +} + +inline int rc_intern_randomize(double n) +{ + srand(n); + return 0; +} + +inline int rc_intern_rand(int n) +{ + return (int)( (rand() / double(RAND_MAX))*(double(n) + ( n < 0 ? 0.001 : -0.001 )) ); +} + +inline double rc_intern_round(double n) +{ + return round(n); +} + +inline int rc_intern_sign(double n) +{ + if(n == 0) + return 0; + else if(n > 0) + return 1; + else + return -1; +} + +inline double rc_intern_sin(double angle) +{ + return sin(angle); +} + +inline double rc_intern_sqrt(double n) +{ + return sqrt(n); +} + +inline double rc_intern_tan(double angle) +{ + return tan(angle); +} + +inline double rc_intern_xorbit(uint64_t a, uint64_t b) +{ + return (a ^ b); +} + +inline int rc_intern_fileOpen(int fo_stream, string fo_file, int fo_mode) +{ + if(fo_stream >= 0 && fo_stream < RC_MAX_FILES) + { + if(rc_fstream[fo_stream] != NULL) + return 0; + + rc_eof[fo_stream] = false; + + switch(fo_mode) + { + case RC_FILE_IO_TEXT_INPUT: + //rc_fstream[fo_stream].open(fo_file.c_str(), fstream::in); + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(), "r"); + //cout << "RC_DEBUG_TEXT_INPUT" << endl; + break; + case RC_FILE_IO_TEXT_OUTPUT: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"w"); + break; + case RC_FILE_IO_TEXT_APPEND: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"a"); + break; + case RC_FILE_IO_TEXT_INPUT_UPDATE: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"r+"); + break; + case RC_FILE_IO_TEXT_OUTPUT_UPDATE: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"w+"); + break; + case RC_FILE_IO_TEXT_APPEND_UPDATE: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"a+"); + break; + case RC_FILE_IO_BINARY_INPUT: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"rb"); + break; + case RC_FILE_IO_BINARY_OUTPUT: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"wb"); + break; + case RC_FILE_IO_BINARY_APPEND: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"ab"); + break; + case RC_FILE_IO_BINARY_INPUT_UPDATE: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"rb+"); + break; + case RC_FILE_IO_BINARY_OUTPUT_UPDATE: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"wb+"); + break; + case RC_FILE_IO_BINARY_APPEND_UPDATE: + rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"ab+"); + break; + } + if(rc_fstream[fo_stream] == NULL) + { + //cout << "RC_DEBUG: FILE NOT OPEN" << endl; + return 0; + } + } + return 1; +} + +inline int rc_intern_fileClose(int fc_stream) +{ + rc_eof[fc_stream] = false; + + if(rc_fstream[fc_stream] != NULL) + { + SDL_RWclose(rc_fstream[fc_stream]); + rc_fstream[fc_stream] = NULL; + return 1; + } + else + return 0; +} + +inline int rc_intern_fileReadByte(int f_stream) +{ + unsigned char buf; + if(SDL_RWread(rc_fstream[f_stream], &buf, 1, 1)==0) + rc_eof[f_stream] = true; + + //SDL_RWtell(rc_fstream[f_stream]); + return (int)buf; +} + +inline uint64_t rc_intern_fileReadByteBuffer(int f_stream, double * buf, uint64_t buf_size) //size is in bytes +{ + uint8_t c_buf[buf_size]; + uint64_t actual_size = SDL_RWread(rc_fstream[f_stream], &c_buf, 1, buf_size); + + if(actual_size==0) + rc_eof[f_stream] = true; + + for(uint64_t i = 0; i < actual_size; i ++) + buf[i] = (double)c_buf[i]; + + return actual_size; +} + +inline uint64_t rc_intern_fileWriteByteBuffer(int f_stream, double * buf, uint64_t buf_size) //size is in bytes +{ + uint8_t c_buf[buf_size]; + for(uint64_t i = 0; i < buf_size; i++) + { + c_buf[i] = (uint8_t)buf[i]; + } + return SDL_RWwrite(rc_fstream[f_stream], &c_buf, 1, buf_size); +} + +inline int rc_intern_fileWriteByte(int f_stream, char wb) +{ + SDL_RWwrite(rc_fstream[f_stream], &wb, 1, 1); + return 1; +} + +inline string rc_intern_fileReadLine(int f_stream) +{ + string rline = ""; + unsigned char buf[5]; + if(SDL_RWread(rc_fstream[f_stream], buf, 1, 1)==0) + { + rc_eof[f_stream] = true; + return ""; + } + while(buf[0]!='\0' && buf[0]!='\n' && buf[0]!='\r') + { + rline.append(1,buf[0]); + if(SDL_RWread(rc_fstream[f_stream], buf, 1, 1)==0) + { + rc_eof[f_stream] = true; + break; + } + } + if(buf[0]=='\r') + SDL_RWread(rc_fstream[f_stream], buf, 1, 1); + + return rline; +} + +inline int rc_intern_fileWrite(int f_stream, string line) +{ + //cout << "DEBUG: WRITELINE" << endl; + if(rc_fstream[f_stream]!=NULL) + SDL_RWwrite(rc_fstream[f_stream], line.c_str(), line.length(), 1); + //cout << "WRITELINE_END" << endl; + return 1; +} + +inline int rc_intern_fileWriteLine(int f_stream, string line) +{ + //cout << "DEBUG: WRITELINE" << endl; + string line_out = line + "\n"; + if(rc_fstream[f_stream]!=NULL) + SDL_RWwrite(rc_fstream[f_stream], line_out.c_str(), line_out.length(), 1); + //cout << "WRITELINE_END" << endl; + return 1; +} + +inline int rc_intern_fileCopy(string src_file, string dst_file) +{ + std::ifstream src(src_file.c_str(), std::ios::binary); + std::ofstream dst(dst_file.c_str(), std::ios::binary); + if(!(src.is_open() && dst.is_open())) + { + if(src.is_open()) + src.close(); + if(dst.is_open()) + dst.close(); + return 0; + } + dst << src.rdbuf(); + src.close(); + dst.close(); + return 1; +} + +inline int rc_intern_fileDelete(string tgt_file) +{ + if(remove(tgt_file.c_str())==0) + return 1; + else + return 0; +} + +inline int rc_intern_fileExist(string tgt_file) +{ + std::ifstream infile(tgt_file.c_str()); + bool fx = infile.good(); + infile.close(); + return (int)fx; +} + +inline int rc_intern_fileMove(string src, string dst) +{ + int fm = rename(src.c_str(), dst.c_str()); + if(fm == 0) + return 1; + else + return 0; +} + +inline int rc_intern_fileRename(string src, string dst) +{ + int fm = rename(src.c_str(), dst.c_str()); + if(fm == 0) + return 1; + else + return 0; +} + +inline unsigned long rc_intern_fileLength(string filename) +{ + //struct stat st; + SDL_RWops * fl_file = SDL_RWFromFile(filename.c_str(), "r"); + Sint64 fl_size = SDL_RWsize(fl_file); + SDL_RWclose(fl_file); + return fl_size; +} + +inline Sint64 rc_intern_fileTell(int f_stream) +{ + return SDL_RWtell(rc_fstream[f_stream]); +} + +inline Sint64 rc_intern_fileSeek(int f_stream, uint64_t pos) +{ + return SDL_RWseek(rc_fstream[f_stream],pos,RW_SEEK_SET); +} + +inline int rc_intern_eof(int f_stream) +{ + //Uint32 current_pos = SDL_RWtell(rc_fstream[(int)rc_nid[EOF_STREAM][0]]); + //Uint32 current_pos = SDL_RWseek(rc_fstream[(int)rc_nid[EOF_STREAM][0],0,RW_SEEK_CUR); + //Uint32 file_eof = SDL_RWseek(rc_fstream[(int)rc_nid[EOF_STREAM][0]],0,RW_SEEK_END); + //SDL_RWseek(rc_fstream[(int)rc_nid[EOF_STREAM][0]],0,current_pos); + return rc_eof[f_stream]; +} + +inline int rc_intern_freeFile() +{ + for(int i = 0; i < RC_MAX_FILES; i++) + if(rc_fstream[i] == NULL) + return i; + return -1; +} + +#ifndef RC_WINDOWS + +#ifdef RC_LINUX +inline int rc_intern_dirChange(string ch_path) +{ + if(chdir(ch_path.c_str())!=0) + { + cout << "Error: Could not change directory\n"; + return 2; + } + rc_dir_path = get_current_dir_name(); + return 0; +} +#endif // RC_LINUX + +inline int rc_intern_dirExist(string d_path) +{ + struct stat info; + + if(stat( d_path.c_str(), &info ) != 0) + return 0; + else if(info.st_mode & S_IFDIR) + return 1; + else + return 0; +} + +inline string rc_intern_dirFirst () +{ + rc_dir = opendir (rc_dir_path.c_str()); + //string s = ""; + + if ((rc_entry = readdir (rc_dir)) != NULL) + { + //cout << "ERROR: " << rc_entry->d_name; + return rc_entry->d_name; + } + return ""; +} + +#ifdef RC_GETCWD +string getcwd_str() +{ + char *buffer = new char[MAXPATHLEN]; + getcwd(buffer,MAXPATHLEN); + if(buffer != NULL) + { + string ret(buffer); + delete[] buffer; + return ret; + } + else + { + return string(); + } +} + + +inline int rc_intern_dirChange(string ch_path) +{ + if(chdir(ch_path.c_str())!=0) + { + cout << "Error: Could not change directory\n"; + return 2; + } + rc_dir_path = getcwd_str(); + return 0; +} + +inline string rc_intern_dir() +{ + string d = getcwd_str(); + //__android_log_print(ANDROID_LOG_ERROR, "RC_DEBUG_DIR", "%s", SDL_GetPrefPath("rcbasic","lucky")); + if(d.compare("")==0) + { + //cout << "Could not get current directory" << endl; + return ""; + } + rc_dir_path = d; + return d; +} + +#else + +inline string rc_intern_dir() +{ + string d = get_current_dir_name(); + if(d.compare("")==0) + { + cout << "Could not get current directory" << endl; + return ""; + } + rc_dir_path = d; + return d; +} + +#endif // RC_ANDROID + +inline string rc_intern_dirNext() +{ + if( (rc_entry = readdir(rc_dir))!=NULL) + return rc_entry->d_name; + return ""; +} + +inline int rc_intern_dirCreate(string d_path) +{ + if(mkdir(d_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)!=0) + { + cout << "ERROR: Could not make directory" << endl; + return 0; + } + return 1; +} + +inline int rc_intern_dirDelete(string d_path) +{ + if(rmdir(d_path.c_str())!=0) + { + cout << "ERROR: Could not delete directory" << endl; + return 0; + } + return 1; +} + +inline string rc_intern_OS() +{ + #ifdef RC_WEB + return "WEB"; + #endif // RC_WEB + + #ifdef RC_LINUX + return "LINUX"; + #endif // RC_LINUX + + #ifdef RC_ANDROID + return "ANDROID"; + #endif // RC_LINUX + + #ifdef RC_MAC + return "MAC"; + #endif // RC_MAC + + #ifdef RC_IOS + return "IOS"; + #endif // RC_IOS +} + +#else + +std::string ConvertWideToANSI(const std::wstring& wstr) +{ + int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); + std::string str(count, 0); + WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL); + return str; +} + +std::wstring ConvertAnsiToWide(const std::string& str) +{ + int count = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0); + std::wstring wstr(count, 0); + MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &wstr[0], count); + return wstr; +} + +std::string ConvertWideToUtf8(const std::wstring& wstr) +{ + int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); + std::string str(count, 0); + WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL); + return str; +} + +std::wstring ConvertUtf8ToWide(const std::string& str) +{ + int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); + std::wstring wstr(count, 0); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count); + return wstr; +} + +inline int rc_intern_dirChange(string dpath) +{ + if(SetCurrentDirectoryW(ConvertUtf8ToWide(dpath).c_str())==0) + { + cout << "[DBG]Error: Could not change directory\n"; + return 2; + } + + DWORD nBufferLength = MAX_PATH; + wchar_t szCurrentDirectory[MAX_PATH + 1]; + GetCurrentDirectoryW(nBufferLength, szCurrentDirectory); + szCurrentDirectory[MAX_PATH] = '\0'; + + rc_dir_path = ConvertWideToUtf8(szCurrentDirectory); + return 0; +} + +bool dirExists(const std::string& dirName_in) +{ + DWORD ftyp = GetFileAttributesW(ConvertUtf8ToWide(dirName_in).c_str()); + if (ftyp == INVALID_FILE_ATTRIBUTES) + return false; //something is wrong with your path! + + if (ftyp & FILE_ATTRIBUTE_DIRECTORY) + return true; // this is a directory! + + return false; // this is not a directory! +} + +inline int rc_intern_dirExist(string dpath) +{ + return dirExists(dpath); +} + +HANDLE hFind; +WIN32_FIND_DATAW ffd; + +string rc_intern_dirFirst() +{ + + //char* path = new char[rc_dir_path.length()+1]; + //*path = rc_dir_path.c_str(); + + //for(int i = 0; i < rc_dir_path.length(); i++) + // path[i] = rc_dir_path[i]; + //path[rc_dir_path.length()] = '\0'; + + //cout << "path = " << path << endl; + //if (path[_tcslen(path) - 1] != '\\') + // _tcscat(path, _T("\\")); + //_tcscat(path, _T("*.*")); + + + string path = rc_dir_path; + + if(path.substr(path.length()-1, 1).compare("\\")!=0) + path += "\\"; + + path += "*.*"; + + //cout << "path2 = " << path << endl; + + hFind = FindFirstFileW(ConvertUtf8ToWide(path).c_str(), &ffd); + //delete path; + //path = NULL; + if (hFind == INVALID_HANDLE_VALUE) + { + cerr << _T("Invalid handle value.") << GetLastError() << endl; + return ""; + } + string fname_utf8 = ConvertWideToUtf8(ffd.cFileName); + return fname_utf8; +} + +inline string rc_intern_dir() +{ + wchar_t buf[MAX_PATH+1]; + GetCurrentDirectoryW(MAX_PATH, buf); + buf[MAX_PATH] = '/0'; + std::wstring d = buf; + + if(d.length()==0) + { + cout << "Could not get current directory" << endl; + return ""; + } + return ConvertWideToUtf8(d.c_str()); +} + +string rc_intern_dirNext() +{ + if(!FindNextFileW(hFind,&ffd)) + return ""; + return ConvertWideToUtf8(ffd.cFileName); +} + +inline int rc_intern_dirCreate(string dpath) +{ + if(CreateDirectoryW(ConvertUtf8ToWide(dpath).c_str(),NULL)==0) + { + cout << "ERROR: Could not make directory" << endl; + return 0; + } + return 1; +} + +inline int rc_intern_dirDelete(string dpath) +{ + if(RemoveDirectoryW(ConvertUtf8ToWide(dpath).c_str())==0) + { + cout << "ERROR: Could not delete directory" << endl; + return 0; + } + return 1; +} + +inline string rc_intern_OS() +{ + return "WINDOWS"; +} + +#endif // RC_WINDOWS + + +inline string rc_intern_date() +{ + time_t t = time(0); // get time now + struct tm * now = localtime( & t ); + stringstream d; + if( now->tm_mon+1 < 10) + d << "0" << now->tm_mon + 1 << "-"; + else + d << now->tm_mon+1 << "-"; + if(now->tm_mday < 10) + d << "0" << now->tm_mday << "-"; + else + d<< now->tm_mday << "-"; + d << (now->tm_year + 1900); + return d.str(); +} + +string ZeroPadNumber(int num) +{ + stringstream ss; + // the number is converted to string with the help of stringstream + ss << num; + string ret; + ss >> ret; + // Append zero chars + int str_length = ret.length(); + for (int i = 0; i < 2 - str_length; i++) + ret = "0" + ret; + return ret; +} + +string rc_intern_easter(int X) +{ + stringstream ss; // X = year to compute + int K, M, S, A, D, R, OG, SZ, OE; + K = X / 100; // Secular number + M = 15 + (3 * K + 3) / 4 - (8 * K + 13) / 25; // Secular Moon shift + S = 2 - (3 * K + 3) / 4; // Secular sun shift + A = X % 19; // Moon parameter + D = (19 * A + M) % 30; // Seed for 1st full Moon in spring + R = D / 29 + (D / 28 - D / 29) * (A / 11); // Calendarian correction quantity + OG = 21 + D - R; // Easter limit + SZ = 7 - (X + X / 4 + S) % 7; // 1st sunday in March + OE = 7 - (OG - SZ) % 7; // Distance Easter sunday from Easter limit in days + //Easter = DateSerial(X, 3, OG + OE); // Result: Easter sunday as number of days in March + ss << ZeroPadNumber(((OG + OE)>31)?4:3) << "-" << ZeroPadNumber((((OG + OE)%31)==0)?31:((OG + OE)%31)) << "-" << X; + return ss.str(); +} + +inline unsigned long rc_intern_ticks() +{ + return clock(); +} + +inline string rc_intern_time() +{ + time_t t = time(0); // get time now + struct tm * now = localtime( & t ); + stringstream d; + if( now->tm_hour < 10) + d << "0" << now->tm_hour << ":"; + else + d << now->tm_hour << ":"; + + if(now->tm_min < 10) + d << "0" << now->tm_min << ":"; + else + d<< now->tm_min << ":"; + + if(now->tm_sec < 10) + d << "0" << now->tm_sec; + else + d << now->tm_sec; + return d.str(); +} + +inline double rc_intern_timer() +{ + return SDL_GetTicks(); + //return clock() / (double)(CLOCKS_PER_SEC / 1000); +} + +inline void rc_intern_wait(double m_sec) +{ + SDL_Delay(m_sec); +} + +inline int rc_intern_system(string rc_sys_cmd) +{ +#ifdef RC_IOS + return 0; +#else + return system(rc_sys_cmd.c_str()); +#endif +} + +inline string rc_intern_sysReturnOutput(string rc_sys_cmd) +{ + #if defined(RC_ANDROID) || defined(RC_IOS) || defined(RC_WEB) + return ""; + #else + const char * cmd = rc_sys_cmd.c_str(); + char buffer[128]; + std::string result = ""; + FILE* pipe = popen(cmd, "r"); + if (!pipe) throw std::runtime_error("popen() failed!"); + try { + while (fgets(buffer, sizeof buffer, pipe) != NULL) { + result += buffer; + } + } catch (...) { + pclose(pipe); + throw; + } + pclose(pipe); + return result; + #endif +} + +inline string rc_intern_command(int num) +{ + if(num < rc_cmd_count) + { + return rc_cmd_args[num]; + } + return ""; +} + +inline int rc_intern_numCommands() +{ + return rc_cmd_count; +} + +inline string rc_intern_env(string v) +{ + #ifdef RC_WINDOWS + char * val = new char[32767]; + int n = GetEnvironmentVariable(v.c_str(), val, 32767); + string rtn = ""; + if (n>0) + rtn = (string)val; + delete val; + return rtn; + #else + char * c = getenv(v.c_str()); + if(c != NULL) + return (string) c; + return ""; + #endif +} + +inline int rc_intern_setEnv(string name, string value, int overwrite) +{ + #ifdef RC_WINDOWS + //string env_cmd = name + "=" + value; + return SetEnvironmentVariable(name.c_str(), value.c_str()) ? 1 : 0; + //return _putenv(name.c_str()); + #else + return setenv(name.c_str(), value.c_str(), overwrite); + #endif +} + +inline string rc_intern_prefPath(string org_name, string app_name) +{ + return (string) SDL_GetPrefPath(org_name.c_str(), app_name.c_str()); +} + +inline int rc_intern_push_n(double n) +{ + rc_user_n_stack[rc_user_active_n_stack].push(n); + return 1; +} + +inline int rc_intern_push_s(string s) +{ + rc_user_s_stack[rc_user_active_s_stack].push(s); + return 1; +} + +inline double rc_intern_pop_n() +{ + double n = rc_user_n_stack[rc_user_active_n_stack].top(); + rc_user_n_stack[rc_user_active_n_stack].pop(); + return n; +} + +inline string rc_intern_pop_s() +{ + string s = rc_user_s_stack[rc_user_active_s_stack].top(); + rc_user_s_stack[rc_user_active_s_stack].pop(); + return s; +} + +inline unsigned long rc_intern_n_stack_size() +{ + return rc_user_n_stack[rc_user_active_n_stack].size(); +} + +inline unsigned long rc_intern_s_stack_size() +{ + return rc_user_s_stack[rc_user_active_s_stack].size(); +} + +inline void rc_intern_getPowerInfo(double * status, double * secs, double * pct) +{ + int s = 0; + int p = 0; + SDL_PowerState p_state = SDL_GetPowerInfo(&s, &p); + *secs = (double)s; + *pct = (double)p; + if(p_state == SDL_POWERSTATE_UNKNOWN) + *status = 0; + else if(p_state == SDL_POWERSTATE_ON_BATTERY) + *status = 1; + else if(p_state == SDL_POWERSTATE_NO_BATTERY) + *status = 2; + else if(p_state == SDL_POWERSTATE_CHARGING) + *status = 3; + else if(p_state == SDL_POWERSTATE_CHARGED) + *status = 4; + else + *status = -1; +} + +int rc_intern_systemRam() +{ + return SDL_GetSystemRAM(); +} + +#ifdef RC_WEB +string rc_intern_evalJS(string js_code) +{ + return emscripten_run_script_string(js_code.c_str()); +} +#else +string rc_intern_evalJS(string js_code) +{ + return "ONLY IN WEB"; +} +#endif + + +//MOBILE OS STUFF +inline string rc_intern_android_getInternalStoragePath() +{ + #ifdef RC_ANDROID + return SDL_AndroidGetInternalStoragePath(); + #else + return ""; + #endif +} + +inline string rc_intern_android_getExternalStoragePath() +{ + #ifdef RC_ANDROID + return SDL_AndroidGetExternalStoragePath(); + #else + return ""; + #endif +} + +inline int rc_intern_android_getExternalStorageState() +{ + #ifdef RC_ANDROID + return SDL_AndroidGetExternalStorageState(); + #else + return 0; + #endif +} + +string rc_intern_android_jni_message(string arg_c) +{ + #ifdef RC_ANDROID + + // retrieve the JNI environment. + JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv(); + + // retrieve the Java instance of the SDLActivity + jobject activity = (jobject)SDL_AndroidGetActivity(); + + // find the Java class of the activity. It should be SDLActivity or a subclass of it. + jclass clazz(env->GetObjectClass(activity)); + + //return "### what the balls :-) "; + + jmethodID rcbasic_android_method = env->GetStaticMethodID(clazz, "rcbasic_android_interface", "(Ljava/lang/String;)Ljava/lang/String;"); + + jstring arg = env->NewStringUTF(arg_c.c_str()); + + jstring rv = (jstring)env->CallStaticObjectMethod(clazz, rcbasic_android_method, arg); + const char * strReturn = env->GetStringUTFChars( rv, 0); + + env->ReleaseStringUTFChars(rv, strReturn); + + // clean up the local references. + env->DeleteLocalRef(activity); + env->DeleteLocalRef(clazz); + + return (string)strReturn; + + #else + return ""; + #endif +} + +#ifdef RC_IOS + #include "rcbasic_ios_native.h" +#else + string rc_intern_runtime_utility(string arg) + { + return ""; + } +#endif + +#endif // RC_STDLIB_H_INCLUDED diff --git a/rcbasic_runtime/resource.rc b/rcbasic_runtime/resource.rc new file mode 100644 index 0000000..e047385 --- /dev/null +++ b/rcbasic_runtime/resource.rc @@ -0,0 +1 @@ +MAINICON ICON "rcbasic.ico" diff --git a/rcbasic_runtime/theoraplay.c b/rcbasic_runtime/theoraplay.c new file mode 100644 index 0000000..232b945 --- /dev/null +++ b/rcbasic_runtime/theoraplay.c @@ -0,0 +1,820 @@ +/** + * TheoraPlay; multithreaded Ogg Theora/Ogg Vorbis decoding. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +// I wrote this with a lot of peeking at the Theora example code in +// libtheora-1.1.1/examples/player_example.c, but this is all my own +// code. + +#include +#include +#include +#include +#include "SDL2/SDL.h" + +#ifdef _WIN32 +#include +#define THEORAPLAY_THREAD_T HANDLE +#define THEORAPLAY_MUTEX_T HANDLE +#define sleepms(x) Sleep(x) +#else +#include +#include +#define sleepms(x) usleep((x) * 1000) +#define THEORAPLAY_THREAD_T pthread_t +#define THEORAPLAY_MUTEX_T pthread_mutex_t +#endif + +#include "theoraplay.h" +#include "theora/theoradec.h" +#include "vorbis/codec.h" + +#define THEORAPLAY_INTERNAL 1 + +typedef THEORAPLAY_VideoFrame VideoFrame; +typedef THEORAPLAY_AudioPacket AudioPacket; + +// !!! FIXME: these all count on the pixel format being TH_PF_420 for now. + +typedef unsigned char *(*ConvertVideoFrameFn)(const th_info *tinfo, + const th_ycbcr_buffer ycbcr); + +static unsigned char *ConvertVideoFrame420ToYUVPlanar( + const th_info *tinfo, const th_ycbcr_buffer ycbcr, + const int p0, const int p1, const int p2) +{ + int i; + const int w = tinfo->pic_width; + const int h = tinfo->pic_height; + const int yoff = (tinfo->pic_x & ~1) + ycbcr[0].stride * (tinfo->pic_y & ~1); + const int uvoff = (tinfo->pic_x / 2) + (ycbcr[1].stride) * (tinfo->pic_y / 2); + unsigned char *yuv = (unsigned char *) malloc(w * h * 2); + if (yuv) + { + unsigned char *dst = yuv; + for (i = 0; i < h; i++, dst += w) + memcpy(dst, ycbcr[p0].data + yoff + ycbcr[p0].stride * i, w); + for (i = 0; i < (h / 2); i++, dst += w/2) + memcpy(dst, ycbcr[p1].data + uvoff + ycbcr[p1].stride * i, w / 2); + for (i = 0; i < (h / 2); i++, dst += w/2) + memcpy(dst, ycbcr[p2].data + uvoff + ycbcr[p2].stride * i, w / 2); + } // if + + return yuv; +} // ConvertVideoFrame420ToYUVPlanar + + +static unsigned char *ConvertVideoFrame420ToYV12(const th_info *tinfo, + const th_ycbcr_buffer ycbcr) +{ + return ConvertVideoFrame420ToYUVPlanar(tinfo, ycbcr, 0, 2, 1); +} // ConvertVideoFrame420ToYV12 + + +static unsigned char *ConvertVideoFrame420ToIYUV(const th_info *tinfo, + const th_ycbcr_buffer ycbcr) +{ + return ConvertVideoFrame420ToYUVPlanar(tinfo, ycbcr, 0, 1, 2); +} // ConvertVideoFrame420ToIYUV + + +// RGB +#define THEORAPLAY_CVT_FNNAME_420 ConvertVideoFrame420ToRGB +#define THEORAPLAY_CVT_RGB_ALPHA 0 +#include "theoraplay_cvtrgb.h" +#undef THEORAPLAY_CVT_RGB_ALPHA +#undef THEORAPLAY_CVT_FNNAME_420 + +// RGBA +#define THEORAPLAY_CVT_FNNAME_420 ConvertVideoFrame420ToRGBA +#define THEORAPLAY_CVT_RGB_ALPHA 1 +#include "theoraplay_cvtrgb.h" +#undef THEORAPLAY_CVT_RGB_ALPHA +#undef THEORAPLAY_CVT_FNNAME_420 + + +typedef struct TheoraDecoder +{ + // Thread wrangling... + int thread_created; + THEORAPLAY_MUTEX_T lock; + volatile int halt; + int thread_done; + THEORAPLAY_THREAD_T worker; + + // API state... + THEORAPLAY_Io *io; + unsigned int maxframes; // Max video frames to buffer. + volatile unsigned int prepped; + volatile unsigned int videocount; // currently buffered frames. + volatile unsigned int audioms; // currently buffered audio samples. + volatile int hasvideo; + volatile int hasaudio; + volatile int decode_error; + + THEORAPLAY_VideoFormat vidfmt; + ConvertVideoFrameFn vidcvt; + + VideoFrame *videolist; + VideoFrame *videolisttail; + + AudioPacket *audiolist; + AudioPacket *audiolisttail; +} TheoraDecoder; + + +#ifdef _WIN32 +static inline int Thread_Create(TheoraDecoder *ctx, void *(*routine) (void*)) +{ + ctx->worker = CreateThread( + NULL, + 0, + (LPTHREAD_START_ROUTINE) routine, + (LPVOID) ctx, + 0, + NULL + ); + return (ctx->worker == NULL); +} +static inline void Thread_Join(THEORAPLAY_THREAD_T thread) +{ + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); +} +static inline int Mutex_Create(TheoraDecoder *ctx) +{ + ctx->lock = CreateMutex(NULL, FALSE, NULL); + return (ctx->lock == NULL); +} +static inline void Mutex_Destroy(THEORAPLAY_MUTEX_T mutex) +{ + CloseHandle(mutex); +} +static inline void Mutex_Lock(THEORAPLAY_MUTEX_T mutex) +{ + WaitForSingleObject(mutex, INFINITE); +} +static inline void Mutex_Unlock(THEORAPLAY_MUTEX_T mutex) +{ + ReleaseMutex(mutex); +} +#else +static inline int Thread_Create(TheoraDecoder *ctx, void *(*routine) (void*)) +{ + return pthread_create(&ctx->worker, NULL, routine, ctx); +} +static inline void Thread_Join(THEORAPLAY_THREAD_T thread) +{ + pthread_join(thread, NULL); +} +static inline int Mutex_Create(TheoraDecoder *ctx) +{ + return pthread_mutex_init(&ctx->lock, NULL); +} +static inline void Mutex_Destroy(THEORAPLAY_MUTEX_T mutex) +{ + pthread_mutex_destroy(&mutex); +} +static inline void Mutex_Lock(THEORAPLAY_MUTEX_T mutex) +{ + pthread_mutex_lock(&mutex); +} +static inline void Mutex_Unlock(THEORAPLAY_MUTEX_T mutex) +{ + pthread_mutex_unlock(&mutex); +} +#endif + + +static int FeedMoreOggData(THEORAPLAY_Io *io, ogg_sync_state *sync) +{ + long buflen = 4096; + char *buffer = ogg_sync_buffer(sync, buflen); + if (buffer == NULL) + return -1; + + buflen = io->read(io, buffer, buflen); + if (buflen <= 0) + return 0; + + return (ogg_sync_wrote(sync, buflen) == 0) ? 1 : -1; +} // FeedMoreOggData + + +// This massive function is where all the effort happens. +static void WorkerThread(TheoraDecoder *ctx) +{ + // make sure we initialized the stream before using pagein, but the stream + // will know to ignore pages that aren't meant for it, so pass to both. + #define queue_ogg_page(ctx) do { \ + if (tpackets) ogg_stream_pagein(&tstream, &page); \ + if (vpackets) ogg_stream_pagein(&vstream, &page); \ + } while (0) + + unsigned long audioframes = 0; + unsigned long videoframes = 0; + double fps = 0.0; + int was_error = 1; // resets to 0 at the end. + int eos = 0; // end of stream flag. + + // Too much Ogg/Vorbis/Theora state... + ogg_packet packet; + ogg_sync_state sync; + ogg_page page; + int vpackets = 0; + vorbis_info vinfo; + vorbis_comment vcomment; + ogg_stream_state vstream; + int vdsp_init = 0; + vorbis_dsp_state vdsp; + int tpackets = 0; + th_info tinfo; + th_comment tcomment; + ogg_stream_state tstream; + int vblock_init = 0; + vorbis_block vblock; + th_dec_ctx *tdec = NULL; + th_setup_info *tsetup = NULL; + + ogg_sync_init(&sync); + vorbis_info_init(&vinfo); + vorbis_comment_init(&vcomment); + th_comment_init(&tcomment); + th_info_init(&tinfo); + + int bos = 1; + while (!ctx->halt && bos) + { + if (FeedMoreOggData(ctx->io, &sync) <= 0) + goto cleanup; + + // parse out the initial header. + while ( (!ctx->halt) && (ogg_sync_pageout(&sync, &page) > 0) ) + { + ogg_stream_state test; + + if (!ogg_page_bos(&page)) // not a header. + { + queue_ogg_page(ctx); + bos = 0; + break; + } // if + + ogg_stream_init(&test, ogg_page_serialno(&page)); + ogg_stream_pagein(&test, &page); + ogg_stream_packetout(&test, &packet); + + if (!tpackets && (th_decode_headerin(&tinfo, &tcomment, &tsetup, &packet) >= 0)) + { + memcpy(&tstream, &test, sizeof (test)); + tpackets = 1; + } // if + else if (!vpackets && (vorbis_synthesis_headerin(&vinfo, &vcomment, &packet) >= 0)) + { + memcpy(&vstream, &test, sizeof (test)); + vpackets = 1; + } // else if + else + { + // whatever it is, we don't care about it + ogg_stream_clear(&test); + } // else + } // while + } // while + + // no audio OR video? + if (ctx->halt || (!vpackets && !tpackets)) + goto cleanup; + + // apparently there are two more theora and two more vorbis headers next. + while ((!ctx->halt) && ((tpackets && (tpackets < 3)) || (vpackets && (vpackets < 3)))) + { + while (!ctx->halt && tpackets && (tpackets < 3)) + { + if (ogg_stream_packetout(&tstream, &packet) != 1) + break; // get more data? + if (!th_decode_headerin(&tinfo, &tcomment, &tsetup, &packet)) + goto cleanup; + tpackets++; + } // while + + while (!ctx->halt && vpackets && (vpackets < 3)) + { + if (ogg_stream_packetout(&vstream, &packet) != 1) + break; // get more data? + if (vorbis_synthesis_headerin(&vinfo, &vcomment, &packet)) + goto cleanup; + vpackets++; + } // while + + // get another page, try again? + if (ogg_sync_pageout(&sync, &page) > 0) + queue_ogg_page(ctx); + else if (FeedMoreOggData(ctx->io, &sync) <= 0) + goto cleanup; + } // while + + // okay, now we have our streams, ready to set up decoding. + if (!ctx->halt && tpackets) + { + // th_decode_alloc() docs say to check for insanely large frames yourself. + if ((tinfo.frame_width > 99999) || (tinfo.frame_height > 99999)) + goto cleanup; + + // We treat "unspecified" as NTSC. *shrug* + if ( (tinfo.colorspace != TH_CS_UNSPECIFIED) && + (tinfo.colorspace != TH_CS_ITU_REC_470M) && + (tinfo.colorspace != TH_CS_ITU_REC_470BG) ) + { + assert(0 && "Unsupported colorspace."); // !!! FIXME + goto cleanup; + } // if + + if (tinfo.pixel_fmt != TH_PF_420) { assert(0); goto cleanup; } // !!! FIXME + + if (tinfo.fps_denominator != 0) + fps = ((double) tinfo.fps_numerator) / ((double) tinfo.fps_denominator); + + tdec = th_decode_alloc(&tinfo, tsetup); + if (!tdec) goto cleanup; + + // Set decoder to maximum post-processing level. + // Theoretically we could try dropping this level if we're not keeping up. + int pp_level_max = 0; + // !!! FIXME: maybe an API to set this? + //th_decode_ctl(tdec, TH_DECCTL_GET_PPLEVEL_MAX, &pp_level_max, sizeof(pp_level_max)); + th_decode_ctl(tdec, TH_DECCTL_SET_PPLEVEL, &pp_level_max, sizeof(pp_level_max)); + } // if + + // Done with this now. + if (tsetup != NULL) + { + th_setup_free(tsetup); + tsetup = NULL; + } // if + + if (!ctx->halt && vpackets) + { + vdsp_init = (vorbis_synthesis_init(&vdsp, &vinfo) == 0); + if (!vdsp_init) + goto cleanup; + vblock_init = (vorbis_block_init(&vdsp, &vblock) == 0); + if (!vblock_init) + goto cleanup; + } // if + + // Now we can start the actual decoding! + // Note that audio and video don't _HAVE_ to start simultaneously. + + Mutex_Lock(ctx->lock); + ctx->prepped = 1; + ctx->hasvideo = (tpackets != 0); + ctx->hasaudio = (vpackets != 0); + Mutex_Unlock(ctx->lock); + + while (!ctx->halt && !eos) + { + int need_pages = 0; // need more Ogg pages? + int saw_video_frame = 0; + + // Try to read as much audio as we can at once. We limit the outer + // loop to one video frame and as much audio as we can eat. + while (!ctx->halt && vpackets) + { + float **pcm = NULL; + const int frames = vorbis_synthesis_pcmout(&vdsp, &pcm); + if (frames > 0) + { + const int channels = vinfo.channels; + int chanidx, frameidx; + float *samples; + AudioPacket *item = (AudioPacket *) malloc(sizeof (AudioPacket)); + if (item == NULL) goto cleanup; + item->playms = (unsigned long) ((((double) audioframes) / ((double) vinfo.rate)) * 1000.0); + item->channels = channels; + item->freq = vinfo.rate; + item->frames = frames; + item->samples = (float *) malloc(sizeof (float) * frames * channels); + item->next = NULL; + + if (item->samples == NULL) + { + free(item); + goto cleanup; + } // if + + // I bet this beats the crap out of the CPU cache... + samples = item->samples; + for (frameidx = 0; frameidx < frames; frameidx++) + { + for (chanidx = 0; chanidx < channels; chanidx++) + *(samples++) = pcm[chanidx][frameidx]; + } // for + + vorbis_synthesis_read(&vdsp, frames); // we ate everything. + audioframes += frames; + + //printf("Decoded %d frames of audio.\n", (int) frames); + Mutex_Lock(ctx->lock); + ctx->audioms += item->playms; + if (ctx->audiolisttail) + { + assert(ctx->audiolist); + ctx->audiolisttail->next = item; + } // if + else + { + assert(!ctx->audiolist); + ctx->audiolist = item; + } // else + ctx->audiolisttail = item; + Mutex_Unlock(ctx->lock); + } // if + + else // no audio available left in current packet? + { + // try to feed another packet to the Vorbis stream... + if (ogg_stream_packetout(&vstream, &packet) <= 0) + { + if (!tpackets) + need_pages = 1; // no video, get more pages now. + break; // we'll get more pages when the video catches up. + } // if + else + { + if (vorbis_synthesis(&vblock, &packet) == 0) + vorbis_synthesis_blockin(&vdsp, &vblock); + } // else + } // else + } // while + + if (!ctx->halt && tpackets) + { + // Theora, according to example_player.c, is + // "one [packet] in, one [frame] out." + if (ogg_stream_packetout(&tstream, &packet) <= 0) + need_pages = 1; + else + { + ogg_int64_t granulepos = 0; + const int rc = th_decode_packetin(tdec, &packet, &granulepos); + if (rc == TH_DUPFRAME) + videoframes++; // nothing else to do. + else if (rc == 0) // new frame! + { + th_ycbcr_buffer ycbcr; + if (th_decode_ycbcr_out(tdec, ycbcr) == 0) + { + VideoFrame *item = (VideoFrame *) malloc(sizeof (VideoFrame)); + if (item == NULL) goto cleanup; + item->playms = (fps == 0) ? 0 : (unsigned int) ((((double) videoframes) / fps) * 1000.0); + item->fps = fps; + item->width = tinfo.pic_width; + item->height = tinfo.pic_height; + item->format = ctx->vidfmt; + item->pixels = ctx->vidcvt(&tinfo, ycbcr); + item->next = NULL; + + if (item->pixels == NULL) + { + free(item); + goto cleanup; + } // if + + //printf("Decoded another video frame.\n"); + Mutex_Lock(ctx->lock); + if (ctx->videolisttail) + { + assert(ctx->videolist); + ctx->videolisttail->next = item; + } // if + else + { + assert(!ctx->videolist); + ctx->videolist = item; + } // else + ctx->videolisttail = item; + ctx->videocount++; + Mutex_Unlock(ctx->lock); + + saw_video_frame = 1; + } // if + videoframes++; + } // if + } // else + } // if + + if (!ctx->halt && need_pages) + { + const int rc = FeedMoreOggData(ctx->io, &sync); + if (rc == 0) + eos = 1; // end of stream + else if (rc < 0) + goto cleanup; // i/o error, etc. + else + { + while (!ctx->halt && (ogg_sync_pageout(&sync, &page) > 0)) + queue_ogg_page(ctx); + } // else + } // if + + // Sleep the process until we have space for more frames. + if (saw_video_frame) + { + int go_on = !ctx->halt; + //printf("Sleeping.\n"); + while (go_on) + { + // !!! FIXME: This is stupid. I should use a semaphore for this. + Mutex_Lock(ctx->lock); + go_on = !ctx->halt && (ctx->videocount >= ctx->maxframes); + Mutex_Unlock(ctx->lock); + if (go_on) + sleepms(10); + } // while + //printf("Awake!\n"); + } // if + } // while + + was_error = 0; + +cleanup: + ctx->decode_error = (!ctx->halt && was_error); + if (tdec != NULL) th_decode_free(tdec); + if (tsetup != NULL) th_setup_free(tsetup); + if (vblock_init) vorbis_block_clear(&vblock); + if (vdsp_init) vorbis_dsp_clear(&vdsp); + if (tpackets) ogg_stream_clear(&tstream); + if (vpackets) ogg_stream_clear(&vstream); + th_info_clear(&tinfo); + th_comment_clear(&tcomment); + vorbis_comment_clear(&vcomment); + vorbis_info_clear(&vinfo); + ogg_sync_clear(&sync); + ctx->io->close(ctx->io); + ctx->thread_done = 1; +} // WorkerThread + + +static void *WorkerThreadEntry(void *_this) +{ + TheoraDecoder *ctx = (TheoraDecoder *) _this; + WorkerThread(ctx); + //printf("Worker thread is done.\n"); + return NULL; +} // WorkerThreadEntry + + +static long IoFopenRead(THEORAPLAY_Io *io, void *buf, long buflen) +{ + SDL_RWops *f = (SDL_RWops *) io->userdata; + const size_t br = SDL_RWread(f, buf, 1, buflen); + if (br == 0) + return -1; + return (long) br; +} // IoFopenRead + + +static void IoFopenClose(THEORAPLAY_Io *io) +{ + SDL_RWops *f = (SDL_RWops *) io->userdata; + SDL_RWclose(f); + free(io); +} // IoFopenClose + + +THEORAPLAY_Decoder *THEORAPLAY_startDecodeFile(const char *fname, + const unsigned int maxframes, + THEORAPLAY_VideoFormat vidfmt) +{ + THEORAPLAY_Io *io = (THEORAPLAY_Io *) malloc(sizeof (THEORAPLAY_Io)); + if (io == NULL) + return NULL; + + SDL_RWops *f = SDL_RWFromFile(fname, "rb"); + if (f == NULL) + { + free(io); + return NULL; + } // if + + io->read = IoFopenRead; + io->close = IoFopenClose; + io->userdata = f; + return THEORAPLAY_startDecode(io, maxframes, vidfmt); +} // THEORAPLAY_startDecodeFile + + +THEORAPLAY_Decoder *THEORAPLAY_startDecode(THEORAPLAY_Io *io, + const unsigned int maxframes, + THEORAPLAY_VideoFormat vidfmt) +{ + TheoraDecoder *ctx = NULL; + ConvertVideoFrameFn vidcvt = NULL; + + switch (vidfmt) + { + // !!! FIXME: current expects TH_PF_420. + #define VIDCVT(t) case THEORAPLAY_VIDFMT_##t: vidcvt = ConvertVideoFrame420To##t; break; + VIDCVT(YV12) + VIDCVT(IYUV) + VIDCVT(RGB) + VIDCVT(RGBA) + #undef VIDCVT + default: goto startdecode_failed; // invalid/unsupported format. + } // switch + + ctx = (TheoraDecoder *) malloc(sizeof (TheoraDecoder)); + if (ctx == NULL) + goto startdecode_failed; + + memset(ctx, '\0', sizeof (TheoraDecoder)); + ctx->maxframes = maxframes; + ctx->vidfmt = vidfmt; + ctx->vidcvt = vidcvt; + ctx->io = io; + + if (Mutex_Create(ctx) == 0) + { + ctx->thread_created = (Thread_Create(ctx, WorkerThreadEntry) == 0); + if (ctx->thread_created) + return (THEORAPLAY_Decoder *) ctx; + } // if + + Mutex_Destroy(ctx->lock); + +startdecode_failed: + io->close(io); + free(ctx); + return NULL; +} // THEORAPLAY_startDecode + + +void THEORAPLAY_stopDecode(THEORAPLAY_Decoder *decoder) +{ + TheoraDecoder *ctx = (TheoraDecoder *) decoder; + if (!ctx) + return; + + if (ctx->thread_created) + { + ctx->halt = 1; + Thread_Join(ctx->worker); + Mutex_Destroy(ctx->lock); + } // if + + VideoFrame *videolist = ctx->videolist; + while (videolist) + { + VideoFrame *next = videolist->next; + free(videolist->pixels); + free(videolist); + videolist = next; + } // while + + AudioPacket *audiolist = ctx->audiolist; + while (audiolist) + { + AudioPacket *next = audiolist->next; + free(audiolist->samples); + free(audiolist); + audiolist = next; + } // while + + free(ctx); +} // THEORAPLAY_stopDecode + + +int THEORAPLAY_isDecoding(THEORAPLAY_Decoder *decoder) +{ + TheoraDecoder *ctx = (TheoraDecoder *) decoder; + int retval = 0; + if (ctx) + { + Mutex_Lock(ctx->lock); + retval = ( ctx && (ctx->audiolist || ctx->videolist || + (ctx->thread_created && !ctx->thread_done)) ); + Mutex_Unlock(ctx->lock); + } // if + return retval; +} // THEORAPLAY_isDecoding + + +#define GET_SYNCED_VALUE(typ, defval, decoder, member) \ + TheoraDecoder *ctx = (TheoraDecoder *) decoder; \ + typ retval = defval; \ + if (ctx) { \ + Mutex_Lock(ctx->lock); \ + retval = ctx->member; \ + Mutex_Unlock(ctx->lock); \ + } \ + return retval; + +int THEORAPLAY_isInitialized(THEORAPLAY_Decoder *decoder) +{ + GET_SYNCED_VALUE(int, 0, decoder, prepped); +} // THEORAPLAY_isInitialized + + +int THEORAPLAY_hasVideoStream(THEORAPLAY_Decoder *decoder) +{ + GET_SYNCED_VALUE(int, 0, decoder, hasvideo); +} // THEORAPLAY_hasVideoStream + + +int THEORAPLAY_hasAudioStream(THEORAPLAY_Decoder *decoder) +{ + GET_SYNCED_VALUE(int, 0, decoder, hasaudio); +} // THEORAPLAY_hasAudioStream + + +unsigned int THEORAPLAY_availableVideo(THEORAPLAY_Decoder *decoder) +{ + GET_SYNCED_VALUE(unsigned int, 0, decoder, videocount); +} // THEORAPLAY_hasAudioStream + + +unsigned int THEORAPLAY_availableAudio(THEORAPLAY_Decoder *decoder) +{ + GET_SYNCED_VALUE(unsigned int, 0, decoder, audioms); +} // THEORAPLAY_hasAudioStream + + +int THEORAPLAY_decodingError(THEORAPLAY_Decoder *decoder) +{ + GET_SYNCED_VALUE(int, 0, decoder, decode_error); +} // THEORAPLAY_decodingError + + +const THEORAPLAY_AudioPacket *THEORAPLAY_getAudio(THEORAPLAY_Decoder *decoder) +{ + TheoraDecoder *ctx = (TheoraDecoder *) decoder; + AudioPacket *retval; + + Mutex_Lock(ctx->lock); + retval = ctx->audiolist; + if (retval) + { + ctx->audioms -= retval->playms; + ctx->audiolist = retval->next; + retval->next = NULL; + if (ctx->audiolist == NULL) + ctx->audiolisttail = NULL; + } // if + Mutex_Unlock(ctx->lock); + + return retval; +} // THEORAPLAY_getAudio + + +void THEORAPLAY_freeAudio(const THEORAPLAY_AudioPacket *_item) +{ + THEORAPLAY_AudioPacket *item = (THEORAPLAY_AudioPacket *) _item; + if (item != NULL) + { + assert(item->next == NULL); + free(item->samples); + free(item); + } // if +} // THEORAPLAY_freeAudio + + +const THEORAPLAY_VideoFrame *THEORAPLAY_getVideo(THEORAPLAY_Decoder *decoder) +{ + TheoraDecoder *ctx = (TheoraDecoder *) decoder; + VideoFrame *retval; + + Mutex_Lock(ctx->lock); + retval = ctx->videolist; + if (retval) + { + ctx->videolist = retval->next; + retval->next = NULL; + if (ctx->videolist == NULL) + ctx->videolisttail = NULL; + assert(ctx->videocount > 0); + ctx->videocount--; + } // if + Mutex_Unlock(ctx->lock); + + return retval; +} // THEORAPLAY_getVideo + + +void THEORAPLAY_freeVideo(const THEORAPLAY_VideoFrame *_item) +{ + THEORAPLAY_VideoFrame *item = (THEORAPLAY_VideoFrame *) _item; + if (item != NULL) + { + assert(item->next == NULL); + free(item->pixels); + free(item); + } // if +} // THEORAPLAY_freeVideo + +// end of theoraplay.cpp ... + diff --git a/rcbasic_runtime/theoraplay.h b/rcbasic_runtime/theoraplay.h new file mode 100644 index 0000000..bf34479 --- /dev/null +++ b/rcbasic_runtime/theoraplay.h @@ -0,0 +1,85 @@ +/** + * TheoraPlay; multithreaded Ogg Theora/Ogg Vorbis decoding. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#ifndef _INCL_THEORAPLAY_H_ +#define _INCL_THEORAPLAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct THEORAPLAY_Io THEORAPLAY_Io; +struct THEORAPLAY_Io +{ + long (*read)(THEORAPLAY_Io *io, void *buf, long buflen); + void (*close)(THEORAPLAY_Io *io); + void *userdata; +}; + +typedef struct THEORAPLAY_Decoder THEORAPLAY_Decoder; + +/* YV12 is YCrCb, not YCbCr; that's what SDL uses for YV12 overlays. */ +typedef enum THEORAPLAY_VideoFormat +{ + THEORAPLAY_VIDFMT_YV12, /* NTSC colorspace, planar YCrCb 4:2:0 */ + THEORAPLAY_VIDFMT_IYUV, /* NTSC colorspace, planar YCbCr 4:2:0 */ + THEORAPLAY_VIDFMT_RGB, /* 24 bits packed pixel RGB */ + THEORAPLAY_VIDFMT_RGBA /* 32 bits packed pixel RGBA (full alpha). */ +} THEORAPLAY_VideoFormat; + +typedef struct THEORAPLAY_VideoFrame +{ + unsigned int playms; + double fps; + unsigned int width; + unsigned int height; + THEORAPLAY_VideoFormat format; + unsigned char *pixels; + struct THEORAPLAY_VideoFrame *next; +} THEORAPLAY_VideoFrame; + +typedef struct THEORAPLAY_AudioPacket +{ + unsigned int playms; /* playback start time in milliseconds. */ + int channels; + int freq; + int frames; + float *samples; /* frames * channels float32 samples. */ + struct THEORAPLAY_AudioPacket *next; +} THEORAPLAY_AudioPacket; + +THEORAPLAY_Decoder *THEORAPLAY_startDecodeFile(const char *fname, + const unsigned int maxframes, + THEORAPLAY_VideoFormat vidfmt); +THEORAPLAY_Decoder *THEORAPLAY_startDecode(THEORAPLAY_Io *io, + const unsigned int maxframes, + THEORAPLAY_VideoFormat vidfmt); +void THEORAPLAY_stopDecode(THEORAPLAY_Decoder *decoder); + +int THEORAPLAY_isDecoding(THEORAPLAY_Decoder *decoder); +int THEORAPLAY_decodingError(THEORAPLAY_Decoder *decoder); +int THEORAPLAY_isInitialized(THEORAPLAY_Decoder *decoder); +int THEORAPLAY_hasVideoStream(THEORAPLAY_Decoder *decoder); +int THEORAPLAY_hasAudioStream(THEORAPLAY_Decoder *decoder); +unsigned int THEORAPLAY_availableVideo(THEORAPLAY_Decoder *decoder); +unsigned int THEORAPLAY_availableAudio(THEORAPLAY_Decoder *decoder); + +const THEORAPLAY_AudioPacket *THEORAPLAY_getAudio(THEORAPLAY_Decoder *decoder); +void THEORAPLAY_freeAudio(const THEORAPLAY_AudioPacket *item); + +const THEORAPLAY_VideoFrame *THEORAPLAY_getVideo(THEORAPLAY_Decoder *decoder); +void THEORAPLAY_freeVideo(const THEORAPLAY_VideoFrame *item); + +#ifdef __cplusplus +} +#endif + +#endif /* include-once blocker. */ + +/* end of theoraplay.h ... */ + diff --git a/rcbasic_runtime/theoraplay_cvtrgb.h b/rcbasic_runtime/theoraplay_cvtrgb.h new file mode 100644 index 0000000..1118e24 --- /dev/null +++ b/rcbasic_runtime/theoraplay_cvtrgb.h @@ -0,0 +1,74 @@ +/** + * TheoraPlay; multithreaded Ogg Theora/Ogg Vorbis decoding. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#if !THEORAPLAY_INTERNAL +#error Do not include this in your app. It is used internally by TheoraPlay. +#endif + +static unsigned char *THEORAPLAY_CVT_FNNAME_420(const th_info *tinfo, + const th_ycbcr_buffer ycbcr) +{ + const int w = tinfo->pic_width; + const int h = tinfo->pic_height; + unsigned char *pixels = (unsigned char *) malloc(w * h * 4); + if (pixels) + { + unsigned char *dst = pixels; + const int ystride = ycbcr[0].stride; + const int cbstride = ycbcr[1].stride; + const int crstride = ycbcr[2].stride; + const int yoff = (tinfo->pic_x & ~1) + ystride * (tinfo->pic_y & ~1); + const int cboff = (tinfo->pic_x / 2) + (cbstride) * (tinfo->pic_y / 2); + const unsigned char *py = ycbcr[0].data + yoff; + const unsigned char *pcb = ycbcr[1].data + cboff; + const unsigned char *pcr = ycbcr[2].data + cboff; + int posx, posy; + + for (posy = 0; posy < h; posy++) + { + for (posx = 0; posx < w; posx++) + { + // http://www.theora.org/doc/Theora.pdf, 1.1 spec, + // chapter 4.2 (Y'CbCr -> Y'PbPr -> R'G'B') + // These constants apparently work for NTSC _and_ PAL/SECAM. + const float yoffset = 16.0f; + const float yexcursion = 219.0f; + const float cboffset = 128.0f; + const float cbexcursion = 224.0f; + const float croffset = 128.0f; + const float crexcursion = 224.0f; + const float kr = 0.299f; + const float kb = 0.114f; + + const float y = (((float) py[posx]) - yoffset) / yexcursion; + const float pb = (((float) pcb[posx / 2]) - cboffset) / cbexcursion; + const float pr = (((float) pcr[posx / 2]) - croffset) / crexcursion; + const float r = (y + (2.0f * (1.0f - kr) * pr)) * 255.0f; + const float g = (y - ((2.0f * (((1.0f - kb) * kb) / ((1.0f - kb) - kr))) * pb) - ((2.0f * (((1.0f - kr) * kr) / ((1.0f - kb) - kr))) * pr)) * 255.0f; + const float b = (y + (2.0f * (1.0f - kb) * pb)) * 255.0f; + + *(dst++) = (unsigned char) ((r < 0.0f) ? 0.0f : (r > 255.0f) ? 255.0f : r); + *(dst++) = (unsigned char) ((g < 0.0f) ? 0.0f : (g > 255.0f) ? 255.0f : g); + *(dst++) = (unsigned char) ((b < 0.0f) ? 0.0f : (b > 255.0f) ? 255.0f : b); + #if THEORAPLAY_CVT_RGB_ALPHA + *(dst++) = 0xFF; + #endif + } // for + + // adjust to the start of the next line. + py += ystride; + pcb += cbstride * (posy % 2); + pcr += crstride * (posy % 2); + } // for + } // if + + return pixels; +} // THEORAPLAY_CVT_FNNAME_420 + +// end of theoraplay_cvtrgb.h ... +