Posts: 68
Threads: 11
Joined: Apr 2022
Reputation:
5
(01-19-2026, 04:15 PM)Pete Wrote: That's all folks. I have to make some overseas calls on my coconut phone while the rates are still low.
Pete Hi @Pete,
Do you know MiroTalk ?
No registration, no e-mail address, no credit card, no call fees to make worldwide video calls from your prefered web browser.
You can try it at: MiroTalk
Cheers.
Fifi
Before to send the arrow of truth, dip the head in a honey pot (Cheyenne saying).
Don't tell my Mom I'm on iMac with macOS, she thinks I work on PC with Windows.
Posts: 346
Threads: 45
Joined: Jun 2024
Reputation:
32
@Pete
If i made you a thing that literally breaks modern conventions for graphics, worked using the same singular command set and in doing so allowed people with 15 year old laptops to play games online with people that have modern systems (yeah they would see different rendering but the sync and GAME would be cohesive) would you use it? Or cause its underlying system is c/c++ ignore it? (Remember though that QB64 is converted to c++ to compile AND run?)
Let me know as (AND YOU KNOW I LOVE YOU) right now you're digging our grave by even asking this question!
Oh, and just cause i know youll wanna see...youve again led me to be inspired so this is a MULTI rendering system for QB64 that has once again led me to restart GDK dev!
Code: (Select All) #ifndef GDK_SYSTEM_H
#define GDK_SYSTEM_H
/*
GDK_SYSTEM.h - 2026 S-TIER ACTOR CORE
Unified Header-Only Architecture
*/
// --- 1. DATA-ORIENTED STATE (Cache Aligned) ---
struct alignas(64) GDK_ActorState {
int resX, resY, mode, minW, minH;
bool quit, fullscreen, canResize, pointerVisible, rawInputActive;
float deltaTime, fps, targetFrameTime, sensitivity;
uint32_t frameCount;
std::chrono::high_resolution_clock::time_point lastTime;
int mX, mY, mDX, mDY, mOldX, mOldY;
uint8_t mBtn, mBtnPrev;
uint8_t keys[256], keysPrev[256];
WINDOWPLACEMENT wndPrev;
};
static GDK_ActorState* g_Actor = nullptr;
static HDC g_hdc = NULL;
static HGLRC g_hrc = NULL;
static HWND g_hwnd = NULL;
static bool g_LegacyRequest = false;
// --- 2. INTERNAL WINDOW SINK ---
LRESULT CALLBACK GDK_WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
if (!g_Actor) return DefWindowProc(hwnd, msg, wp, lp);
switch (msg) {
case WM_CLOSE: g_Actor->quit = true; return 0;
case WM_INPUT: {
if (!g_Actor->rawInputActive) break;
UINT dwSize = sizeof(RAWINPUT); static BYTE lpb[sizeof(RAWINPUT)];
GetRawInputData((HRAWINPUT)lp, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
RAWINPUT* raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEMOUSE) {
g_Actor->mDX += (int)((float)raw->data.mouse.lLastX * g_Actor->sensitivity);
g_Actor->mDY += (int)((float)raw->data.mouse.lLastY * g_Actor->sensitivity);
}
return 0;
}
case WM_MOUSEMOVE:
g_Actor->mX = (int)(short)LOWORD(lp); g_Actor->mY = (int)(short)HIWORD(lp);
return 0;
case WM_LBUTTONDOWN: g_Actor->mBtn |= 1; return 0; case WM_LBUTTONUP: g_Actor->mBtn &= ~1; return 0;
case WM_RBUTTONDOWN: g_Actor->mBtn |= 2; return 0; case WM_RBUTTONUP: g_Actor->mBtn &= ~2; return 0;
case WM_SIZE:
g_Actor->resX = LOWORD(lp); g_Actor->resY = HIWORD(lp);
glViewport(0, 0, g_Actor->resX, g_Actor->resY);
return 0;
case WM_GETMINMAXINFO: {
LPMINMAXINFO mmi = (LPMINMAXINFO)lp;
if (g_Actor->minW > 0) mmi->ptMinTrackSize.x = g_Actor->minW;
if (g_Actor->minH > 0) mmi->ptMinTrackSize.y = g_Actor->minH;
return 0;
}
case WM_SIZING: if (!g_Actor->canResize) return TRUE; break;
}
return DefWindowProc(hwnd, msg, wp, lp);
}
// --- 3. EXPORTED HARDWARE API ---
GDK_API void GDK_SetLegacy(bool enable) { g_LegacyRequest = enable; }
GDK_API void GDK_SetMouseSensitivity(float s) { if(g_Actor) g_Actor->sensitivity = s; }
GDK_API void GDK_SetMaxFPS(int fps) { if(g_Actor) g_Actor->targetFrameTime = (fps > 0) ? 1.0f / (float)fps : 0.0f; }
GDK_API long long GDK_Boot(int w, int h, const char* title, int mode) {
SetProcessDPIAware();
g_Actor = new GDK_ActorState();
memset(g_Actor, 0, sizeof(GDK_ActorState));
g_Actor->sensitivity = 1.0f; g_Actor->pointerVisible = true; g_Actor->canResize = true;
HINSTANCE inst = GetModuleHandle(NULL);
WNDCLASS wc = {0};
wc.lpfnWndProc = GDK_WndProc; wc.hInstance = inst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = "GDK_ACTOR_2026";
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
int pX = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
int pY = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
g_hwnd = CreateWindow("GDK_ACTOR_2026", title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, pX, pY, w, h, NULL, NULL, inst, NULL);
g_hdc = GetDC(g_hwnd);
PIXELFORMATDESCRIPTOR pfd = {sizeof(pfd), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32};
SetPixelFormat(g_hdc, ChoosePixelFormat(g_hdc, &pfd), &pfd);
HGLRC temp = wglCreateContext(g_hdc);
wglMakeCurrent(g_hdc, temp);
glewInit();
if (mode >= 30 && wglCreateContextAttribsARB) {
int profile = g_LegacyRequest ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
int versions[] = { mode, 46, 45, 33 };
for (int v : versions) {
int attr[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, v/10, WGL_CONTEXT_MINOR_VERSION_ARB, v%10, WGL_CONTEXT_PROFILE_MASK_ARB, profile, 0 };
HGLRC modern = wglCreateContextAttribsARB(g_hdc, 0, attr);
if (modern) { wglDeleteContext(temp); g_hrc = modern; wglMakeCurrent(g_hdc, g_hrc); mode = v; break; }
}
}
if (!g_hrc) g_hrc = temp;
g_Actor->mode = mode;
g_Actor->lastTime = std::chrono::high_resolution_clock::now();
return (long long)g_hwnd;
}
GDK_API void GDK_EnableRawInput() {
RAWINPUTDEVICE Rid = { 0x01, 0x02, 0, g_hwnd };
if(RegisterRawInputDevices(&Rid, 1, sizeof(Rid))) g_Actor->rawInputActive = true;
}
GDK_API void GDK_Sync() {
if (!g_Actor) return;
g_Actor->mOldX = g_Actor->mX; g_Actor->mOldY = g_Actor->mY;
memcpy(g_Actor->keysPrev, g_Actor->keys, 256);
g_Actor->mBtnPrev = g_Actor->mBtn;
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); }
for (int i = 0; i < 256; i++) g_Actor->keys[i] = (GetAsyncKeyState(i) & 0x8000) ? 1 : 0;
if (!g_Actor->rawInputActive) {
g_Actor->mDX = g_Actor->mX - g_Actor->mOldX;
g_Actor->mDY = g_Actor->mY - g_Actor->mOldY;
}
auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> diff = now - g_Actor->lastTime;
if (g_Actor->targetFrameTime > 0) {
while (diff.count() < g_Actor->targetFrameTime) {
std::this_thread::yield();
now = std::chrono::high_resolution_clock::now();
diff = now - g_Actor->lastTime;
}
}
g_Actor->deltaTime = diff.count();
g_Actor->fps = (g_Actor->deltaTime > 0.0f) ? 1.0f / g_Actor->deltaTime : 0.0f;
g_Actor->lastTime = now;
}
// Atomic Visual Commands
GDK_API void GDK_ClearColor(float r, float g, float b, float a) { glClearColor(r, g, b, a); }
GDK_API void GDK_CLS() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
GDK_API void GDK_Display() {
SwapBuffers(g_hdc);
if(g_Actor) { g_Actor->frameCount++; if(g_Actor->rawInputActive){ g_Actor->mDX = 0; g_Actor->mDY = 0; } }
}
// Property Accessors
GDK_API float GDK_GetFPS() { return g_Actor ? g_Actor->fps : 0.0f; }
GDK_API float GDK_GetDelta() { return g_Actor ? g_Actor->deltaTime : 0.0f; }
GDK_API int GDK_ScreenWidth() { return g_Actor ? g_Actor->resX : 0; }
GDK_API int GDK_ScreenHeight() { return g_Actor ? g_Actor->resY : 0; }
GDK_API bool GDK_QuitRequested() { return g_Actor ? g_Actor->quit : false; }
// Input Accessors
GDK_API int GDK_MouseX() { return g_Actor ? g_Actor->mX : 0; }
GDK_API int GDK_MouseY() { return g_Actor ? g_Actor->mY : 0; }
GDK_API int GDK_MouseDX() { return g_Actor ? g_Actor->mDX : 0; }
GDK_API int GDK_MouseDY() { return g_Actor ? g_Actor->mDY : 0; }
GDK_API int GDK_MouseHit(int b) { return (g_Actor->mBtn & b) && !(g_Actor->mBtnPrev & b); }
GDK_API int GDK_KeyHeld(int k) { return g_Actor->keys[k & 0xFF]; }
GDK_API int GDK_KeyHit(int k) { return (g_Actor->keys[k & 0xFF] && !g_Actor->keysPrev[k & 0xFF]); }
GDK_API int GDK_KeyRel(int k) { return (!g_Actor->keys[k & 0xFF] && g_Actor->keysPrev[k & 0xFF]); }
// Window Control
GDK_API void GDK_SetVSync(bool e) { if(wglSwapIntervalEXT) wglSwapIntervalEXT(e ? 1 : 0); }
GDK_API void GDK_AllowResize(bool e) { if(g_Actor) g_Actor->canResize = e; }
GDK_API void GDK_SetPointer(bool v) { if(g_Actor && g_Actor->pointerVisible != v) { ShowCursor(v); g_Actor->pointerVisible = v; } }
GDK_API void GDK_CenterPointer() { if(g_hwnd) { RECT r; GetWindowRect(g_hwnd, &r); SetCursorPos(r.left + (g_Actor->resX / 2), r.top + (g_Actor->resY / 2)); } }
#endif
Now though, if people use it to make stuff, itll work on almost ANY pc since like 2001!
Unseen (A person who will DIE before Qb64 does!)
Posts: 329
Threads: 22
Joined: Apr 2022
Reputation:
60
(01-19-2026, 04:15 PM)Pete Wrote: I'm surprised you didn't recommend Fig BASIC.
I also never understood why you jumped aboard the S.S. Python when the rest of us were having a grand ol' time on Galleon's Island. SDL or OpenGL? Hint: Always go with the one with the bigger coconuts. There's no way
Posts: 68
Threads: 11
Joined: Apr 2022
Reputation:
5
01-21-2026, 03:07 PM
(This post was last modified: 01-21-2026, 04:15 PM by Fifi.)
(01-21-2026, 01:16 PM)vince Wrote: (01-19-2026, 04:15 PM)Pete Wrote: I'm surprised you didn't recommend Fig BASIC.
I also never understood why you jumped aboard the S.S. Python when the rest of us were having a grand ol' time on Galleon's Island. SDL or OpenGL? Hint: Always go with the one with the bigger coconuts.
Cheers. There's no way Hi Vince,
I'm curious: why do you prefer slow interpreted code like Python running in a crapy overloaded VM over fast compiled code like qb64pe executables?
It's no wonder Linus Torvalds preferred integrating Rust into the Linux kernel rather than Python!
Before to send the arrow of truth, dip the head in a honey pot (Cheyenne saying).
Don't tell my Mom I'm on iMac with macOS, she thinks I work on PC with Windows.
Posts: 213
Threads: 5
Joined: Apr 2022
Reputation:
27
Python, ugh.
I will occasionally fire up an interpreter for some quick'n'dirty calculation, but it's usually Basic.
Python is quite powerful, but I'll NEVER understand why the Windows build of a free & open source interpreter is built using an unfree toolchain like MSVC.
It is for that simple fact that I avoid Python.
Besides, I prefer compilers.
Posts: 188
Threads: 14
Joined: May 2024
Reputation:
20
whichever programmer insists heavily on python. on windows must be very demanding. "go ahead and customize it! to get better performance! because i'm never touching ''gcc''! it doesn't even have a real debugger!" but what do i know?
it would be awesome. if qb64 phoenix edition had a "fancy" debugger. more like that of purebasic. but i don't think it was worth the extra 70usd. or more that was tacked onto the price of that other thing.
sadly there are some talented programmers. that know python more than any other language. forcing them to learn c++ or rust. would just stifle them. then one of them claims, "real life work is calling!" or "the wife needs me more at home!" or "there is something else i had been interested in!" then someone else is hired who also "only knows" python. yay!
python is too powerful for me! too powerful for my computer. this is because after downloading about 10mib or so. "pip" has a fit. complains "connection to peer failed" or something like that. trying to go to github. it permanently turned me off. could have been learning python at the end of last year. instead of lisp.
hopeless addict of dying in the first few levels of two particular console viewport "roguelike" games
Posts: 68
Threads: 11
Joined: Apr 2022
Reputation:
5
01-22-2026, 11:07 AM
(This post was last modified: 01-22-2026, 11:13 AM by Fifi.)
With regard to programming languages, below atre some interesting tests for the simple "Hello, World!":
C Source:
Code: (Select All) // hello.c
//
#include <stdio.h>
int main(int argc, const char * argv[]) {
printf("Hello, World!\n");
return 0;
}
Source size: 151 bytes
Executable size: 27,520 bytes
C++ Source:
Code: (Select All) // hello.cpp
//
#include <iostream.h>
int main(int argc, const char * argv[]) {
printf("Hello, World!\n");
return 0;
}
Source size: 159 bytes
Executable size: 36,480 bytes (That's already 35% larger than with C for the same tiny program!)
qb64pe Source:
Code: (Select All) ' hello.bas
'
print("Hello, World!")
Source size: 36 bytes
Executable size: 1,249,892 bytes (+ hello_start.command size: 261 bytes)
Who can explain such a difference in size between all these executables ( which BTW proves that C is more efficient than C++ even for such a tiny program)?
And why such a huge difference especially between the code generated with C++ and that created with qb64pe, since the qb64pe's executable is said to be the generated code of the "basic" language code simply translated into C++ code?
So, what is added to the qb64pe code to create an executable 35 times larger, and why?
I would like to understand, simply to satisfy my curiosity.
Cheers.
Fifi
PS:ASM Source:
; hello.asm (must run on x86 iMac)
;
global start
section .text
start:
mov rax, 0x02000004
mov rdi, 1
mov rsi, message
mov rdx; 14
syscall
mov rax, 0x02000001
xor rdi, rdi
syscall
section .data
message: db "Hello, World!", 10
Source size: 288 bytes
Executable size: ?
Sorry, but at the moment I cannot create the executable on my iMac running High Sierra because I have not yet configured the ASM language for Xcode 10.1, but I will come back with the result once that is done.
Before to send the arrow of truth, dip the head in a honey pot (Cheyenne saying).
Don't tell my Mom I'm on iMac with macOS, she thinks I work on PC with Windows.
Posts: 243
Threads: 15
Joined: Apr 2024
Reputation:
30
(01-22-2026, 11:07 AM)Fifi Wrote: With regard to programming languages, below atre some interesting tests for the simple "Hello, World!":
C Source:
Code: (Select All) // hello.c
//
#include <stdio.h>
int main(int argc, const char * argv[]) {
printf("Hello, World!\n");
return 0;
}
Source size: 151 bytes
Executable size: 27,520 bytes
C++ Source:
Code: (Select All) // hello.cpp
//
#include <iostream.h>
int main(int argc, const char * argv[]) {
printf("Hello, World!\n");
return 0;
}
Source size: 159 bytes
Executable size: 36,480 bytes (That's already 35% larger than with C for the same tiny program!)
qb64pe Source:
Code: (Select All) ' hello.bas
'
print("Hello, World!")
Source size: 36 bytes
Executable size: 1,249,892 bytes (+ hello_start.command size: 261 bytes)
Who can explain such a difference in size between all these executables (which BTW proves that C is more efficient than C++ even for such a tiny program)?
And why such a huge difference especially between the code generated with C++ and that created with qb64pe, since the qb64pe's executable is said to be the generated code of the "basic" language code simply translated into C++ code?
So, what is added to the qb64pe code to create an executable 35 times larger, and why?
I would like to understand, simply to satisfy my curiosity.
Cheers.
Fifi
Lets add this: (Makes QB64PE look A LOT better !)
RUST
fn main() {
println!("Hello World!");
}
44 bytes of source.
Executable size: 13,271,344 BYTES !!!!
Posts: 4,693
Threads: 222
Joined: Apr 2022
Reputation:
322
01-22-2026, 04:08 PM
(This post was last modified: 01-22-2026, 11:52 PM by bplus.)
oh interpreter:
Code: (Select All) . Hello World
https://qb64phoenix.com/forum/showthread...700#pid700
PS: 0 additional bytes .exe
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
(01-22-2026, 12:26 PM)ahenry3068 Wrote: Who can explain such a difference in size between all these executables (which BTW proves that C is more efficient than C++ even for such a tiny program)?
This only proves that higher tier languages package more functions into the EXE than others.
When you compile a QB64 program, you don't just get the code you wrote; you get every function which is attached to QB64.
You didn't use TAN, but it's in there.
You didn't use _PRINTSCREEN, but it's in there.
You didn't use _MEM, but it's in there.
You didn't use $RESIZE, but it's in there.
*ALL* The functions in QB64PE are neatly packed up and attached in the source code that you compile, in case you *DID* want to make use of them.
Them all sitting there, however, has very little impact on the actual program that you're running.
Code: (Select All) PRINT "Hello World"
SUB SORT
SUB OPENFILES
SUB EATCHEETOS
SUB FOO
SUB FOOFOOFOO
Now my program above has one command to execute and half a dozen subs. Since it never calls out to those subs, their impact is really minimal on the performance of the program itself. They might affect memory usage by sitting around when they don't have to, and they might affect load times of the program by 0.001 nanosecond on today's hardware, but as for performance?
They're just unreferenced memory that never gets accessed or called to.
There's no real reason to take the effort to strip them out of every EXE you compile. Just leave them there and forget about them.
So... in the end you get a larger EXE, but performance wise, it performs exactly the same as the smaller program. It just has a bunch of stuff sitting in it which you "COULD" have used, but never did.
That's the difference in the compiled sizes. The more things you can just plug in and let the language do for you, even if you use those things or not, the larger the EXE is going to end up being. It doesn't really affect performance, but it does affect flexibility.
Try to write a nice program of any complexity in C, without importing a single library into it. Draw a "Hello World", make it a graphical image, and then rotate it 360 in a circle.... without any library usage whatsoever. I can do it in QB64 in 3 minutes from start to finish because all the tools are already there. How long would it take to code that from scratch in C?
|