Mix_Music *music = NULL;
For MP3:
Mix_Init(MIX_INIT_MP3);
Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
Mix_Music *music = Mix_LoadMUS("c:\\assembly\\Tennisballen\\x64\\Debug\\test.mp3");
Mix_PlayMusic(music, 1);
or for XM:
Mix_Init(MIX_INIT_MOD);
Mix_OpenAudio(22050, AUDIO_S16SYS, 2, 640);
Mix_Music *music = Mix_LoadMUS("c:\\assembly\\Tennisballen\\x64\\Debug\\tip - kool.xm");
Mix_PlayMusic(music, 1);
To End the music:
Mix_FreeMusic(music);
zaterdag 31 maart 2018
woensdag 28 maart 2018
SDL2 static link
- Download the SDL2 sources.
- Select release configuration.
- In the VisualC folder, open the visual studio solution.
- Change the type of project for SDL2 and SDL2main: General -> Configuration Type -> Static Library
- Configuration Properties -> C/C++ -> Code Generation -> Runtime Library : Multi-threaded (/MT)
- You should obtain: SDL2.lib and SDL2main.lib
Here is the list of dependencies to add in the Linker -> Input of the project you want to compile:
winmm.lib
imm32.lib
version.lib
These libraries are already included in visual studio so it should not be necessary to include them with other lib files.
vrijdag 23 maart 2018
Hoe sinus functie te implementeren
Dit is een interessant antwoord op stackoverflow over hoe je een sinus functie kunt implementeren.
maandag 19 maart 2018
SDL2 fastest way to draw pixels
When your monitor sync is 60 herz, you've got 16 ms to do your pixel update.
I managed to clear a 1366 by 768 pixelbuffer and upload it to the graphicscard in 0.60ms. This leaves 15 ms to do pixel magic.
In SDL 2, I do the following:
#define DIMx 1366
#define DIMy 768
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,DIMx, DIMy,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN */);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED /*| SDL_RENDERER_PRESENTVSYNC */);
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, DIMx, DIMy);
SDL_Surface* surface = SDL_CreateRGBSurface(0, DIMx, DIMy, 32, 0, 0, 0, 0);
BYTE* pixels = (BYTE *)surface->pixels;
SDL_Event event;
bool running = true;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
while (running)
{
int pitch = DIMx * 4;
SDL_LockTexture(texture, NULL, (void **)&pixels, &pitch);
ClearArray(pixels, (DIMx*DIMy/2) ); //0.15 ms (asm: rep stosq)
pixels[0] = 255; //set just one pixel, for example
pixels[1] = 255;
pixels[2] = 255;
pixels[3] = 255;
SDL_UnlockTexture(texture);
SDL_RenderCopyEx(renderer, texture, NULL, NULL, 0.0f, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
}
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
I hope you can use this code. Activate the SDL_RENDERER_PRESENTVSYNC to have a smooth 60 herz.
I managed to clear a 1366 by 768 pixelbuffer and upload it to the graphicscard in 0.60ms. This leaves 15 ms to do pixel magic.
In SDL 2, I do the following:
#define DIMx 1366
#define DIMy 768
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,DIMx, DIMy,SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN */);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED /*| SDL_RENDERER_PRESENTVSYNC */);
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, DIMx, DIMy);
SDL_Surface* surface = SDL_CreateRGBSurface(0, DIMx, DIMy, 32, 0, 0, 0, 0);
BYTE* pixels = (BYTE *)surface->pixels;
SDL_Event event;
bool running = true;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderClear(renderer);
while (running)
{
int pitch = DIMx * 4;
SDL_LockTexture(texture, NULL, (void **)&pixels, &pitch);
ClearArray(pixels, (DIMx*DIMy/2) ); //0.15 ms (asm: rep stosq)
pixels[0] = 255; //set just one pixel, for example
pixels[1] = 255;
pixels[2] = 255;
pixels[3] = 255;
SDL_UnlockTexture(texture);
SDL_RenderCopyEx(renderer, texture, NULL, NULL, 0.0f, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
}
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
Binair bestand downloaden vanuit Javascript
In een eerdere blog heb ik al eens geschreven over createObjectURL, namelijk bij het direct printen vanuit Chrome.
Ook voor het laten downloaden van binaire bestanden is de functie window.URL.createObjectURL handig.
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
var saveByteArray = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var sampleBytes = base64ToArrayBuffer('R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs');
saveByteArray([sampleBytes], 'black1x1.bin');
Voer deze javascript uit en Chrome download meteen een file genaamd black1x1.bin. Lijkt me zelfs een beetje onwenselijk dat een website zomaar een bestand kan laten downloaden zonder dat je ergens op klikt...
Ook voor het laten downloaden van binaire bestanden is de functie window.URL.createObjectURL handig.
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}
var saveByteArray = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var sampleBytes = base64ToArrayBuffer('R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs');
saveByteArray([sampleBytes], 'black1x1.bin');
Voer deze javascript uit en Chrome download meteen een file genaamd black1x1.bin. Lijkt me zelfs een beetje onwenselijk dat een website zomaar een bestand kan laten downloaden zonder dat je ergens op klikt...
zondag 18 maart 2018
Assembler is sneller dan C++
Gisteren een video gezien van een Assembler expert die uitdrukkelijk beweert dat het een leugen is dat C++ tegenwoordig sneller is dan Assembler.
Laten we een test doen. Bijvoorbeeld een array vullen met 0.
Om maximaal nut te hebben van de 64bits architectuur doe ik het volgende in C++:
Uint64* pixels64bit = (Uint64 *)pixels;
for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
Bovenstaande loop duurt 1.05ms.
Nu in Assembler:
ClearArray proc
push rdi
xchg rcx, rdx
mov rdi, rdx
xor rax, rax
rep stosq
pop rdi
ret
ClearArray endp
En dat duurt 0.15ms.
Hoe komt het dat de Assembler versie 8 keer sneller is? Als we naar de gegenereerde code van C++ kijken, dan zien we het:
CPP: Uint64* pixels64bit = (Uint64 *)pixels;
00007FF7F1CE1A9A mov rax,qword ptr [pixels]
00007FF7F1CE1AA1 mov qword ptr [rbp+218h],rax
CPP: for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
00007FF7F1CE1AA8 mov dword ptr [rbp+234h],0
00007FF7F1CE1AB2 jmp wWinMain+1E2h (07FF7F1CE1AC2h)
00007FF7F1CE1AB4 mov eax,dword ptr [rbp+234h]
00007FF7F1CE1ABA inc eax
00007FF7F1CE1ABC mov dword ptr [rbp+234h],eax
00007FF7F1CE1AC2 cmp dword ptr [rbp+234h],80100h
00007FF7F1CE1ACC jge wWinMain+206h (07FF7F1CE1AE6h)
00007FF7F1CE1ACE movsxd rax,dword ptr [rbp+234h]
00007FF7F1CE1AD5 mov rcx,qword ptr [rbp+218h]
00007FF7F1CE1ADC mov qword ptr [rcx+rax*8],0
00007FF7F1CE1AE4 jmp wWinMain+1D4h (07FF7F1CE1AB4h)
Dit kan dus nooit sneller zijn, dan de rep stosq.
Trouwens, een C++ functie zoals:
std::fill(pixels64bit, pixels64bit + (DIMx*DIMy/2), 0);
duurt ook ruim 1.00ms.
Laten we een test doen. Bijvoorbeeld een array vullen met 0.
Om maximaal nut te hebben van de 64bits architectuur doe ik het volgende in C++:
Uint64* pixels64bit = (Uint64 *)pixels;
for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
Bovenstaande loop duurt 1.05ms.
Nu in Assembler:
ClearArray proc
push rdi
xchg rcx, rdx
mov rdi, rdx
xor rax, rax
rep stosq
pop rdi
ret
ClearArray endp
En dat duurt 0.15ms.
Hoe komt het dat de Assembler versie 8 keer sneller is? Als we naar de gegenereerde code van C++ kijken, dan zien we het:
CPP: Uint64* pixels64bit = (Uint64 *)pixels;
00007FF7F1CE1A9A mov rax,qword ptr [pixels]
00007FF7F1CE1AA1 mov qword ptr [rbp+218h],rax
CPP: for (int i = 0; i<(DIMx*DIMy/2); i++) { pixels64bit[i] = 0; }
00007FF7F1CE1AA8 mov dword ptr [rbp+234h],0
00007FF7F1CE1AB2 jmp wWinMain+1E2h (07FF7F1CE1AC2h)
00007FF7F1CE1AB4 mov eax,dword ptr [rbp+234h]
00007FF7F1CE1ABA inc eax
00007FF7F1CE1ABC mov dword ptr [rbp+234h],eax
00007FF7F1CE1AC2 cmp dword ptr [rbp+234h],80100h
00007FF7F1CE1ACC jge wWinMain+206h (07FF7F1CE1AE6h)
00007FF7F1CE1ACE movsxd rax,dword ptr [rbp+234h]
00007FF7F1CE1AD5 mov rcx,qword ptr [rbp+218h]
00007FF7F1CE1ADC mov qword ptr [rcx+rax*8],0
00007FF7F1CE1AE4 jmp wWinMain+1D4h (07FF7F1CE1AB4h)
Dit kan dus nooit sneller zijn, dan de rep stosq.
Trouwens, een C++ functie zoals:
std::fill(pixels64bit, pixels64bit + (DIMx*DIMy/2), 0);
duurt ook ruim 1.00ms.
zondag 4 maart 2018
fading text
When there is a lot of text to be read, you can fade it to white and give a option to read the rest of the text. This is how it is done in css. You put a gradient absolute positioned block over it.
https://jsfiddle.net/pz1nsrLw/14/
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
</div>
height: 100px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
#fading:after {
content:'';
width:100%;
height:5rem;
position:absolute;
left:0;
bottom:0;
background-color: black;
background:linear-gradient(rgba(255,255,255,0), #fff);
}
https://jsfiddle.net/pz1nsrLw/14/
html
<div id="fading">Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
Dit is een tekst geschreven<br/>
</div>
css
#fading {height: 100px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
#fading:after {
content:'';
width:100%;
height:5rem;
position:absolute;
left:0;
bottom:0;
background-color: black;
background:linear-gradient(rgba(255,255,255,0), #fff);
}
vrijdag 2 maart 2018
Welke events zijn er met jquery gekoppeld aan een object?
Op de volgende manier kun je kijken welke events jquery gekoppeld heeft op het object window:
$._data( $(window)[0], "events" )
$._data( $(window)[0], "events" )
Abonneren op:
Posts (Atom)