forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Библиотеки (http://forum.boolean.name/forumdisplay.php?f=124)
-   -   [MP3.0+] Магия inline() (http://forum.boolean.name/showthread.php?t=14731)

YellowAfterlife 15.05.2011 01:03

[MP3.0+] Магия inline()
 
Итак, если вы не заметили, MidletPascal поддерживает вставки (inline) java байт-кодов, начиная с версии 3.0.
Это можно эффективно использовать для расширения программ без использования библиотек.
Так же это позволяет реализовывать вещи, которые библиотеками делаются очень сложно, такие как взаимодействие библиотеки с переменными основной программы, и прямое использование оных в процедурах и функциях.

Поэтому, пользуясь доступными базами знаний по этой теме, я написал и собрал на одну страницу некоторые простые в реализации, но полезные для разработки MP приложений и игр функции и процедуры:

http://yellow.orgfree.com/micro/mpinline/

На момент написания этого сообщения страница содержит 16 функций
, включающих в себя манипуляции над строками, изменение размеров "родных" для MP массивов, функции переназначения вывода в свое изображение, системные функции, и даже две функции, которые можно использовать для попиксельной обработки изображений.

Для последних упомянутых приведу пример:
Эта программа заполняет экран разноцветными полосками, после чего обесцвечивает часть изображения.
PHP код:

program pxproc;
//
var _ipx:array[0..1of integer_iw_ih_ilinteger;
procedure ImageToRGB(imgimagexywhinteger);
begin inline(
iload_3iload_1isubputstatic field 'M','_iw','I';
iload 4iload_2isubputstatic field 'M','_ih','I';
getstatic field 'M','_iw','I'getstatic field 'M','_ih','I'imul;
putstatic field 'M','_il','I'getstatic field 'M','_il','I'newarray 10;
putstatic field 'M','_ipx','[I'aload_0getstatic field 'M','_ipx','[I';
iconst_0iload_3iload_1iload_2iload_3iload 4;
invokevirtual method 'javax/microedition/lcdui/Image','getRGB','([IIIIIII)V';
return;
); 
end;
function 
ImageFromRGB(whinteger): image;
begin inline(
getstatic field 'M','_ipx','[I'iload_0iload_1iconst_1;
invokestatic method 'javax/microedition/lcdui/Image','createRGBImage',
'([IIIZ)Ljavax/microedition/lcdui/Image;'areturn;
); 
end;
//
var ijrgbapinteger;
begin
:= 10;
:= 0;
while 
GetWidth do begin
SetColor
(random(255), random(255), random(255));
FillRect(i0jGetHeight);
:= j;
end;
RePaint;
Delay(1000);
ImageToRGB(ImageFromCanvas(00GetWidth64), 00GetWidth64);
for 
:= 0 to _il-do begin
  p 
:= _ipx[i];
  
// Разбираем цвет пикселя на детали:
  
:= (_ipx[i] and $FF000000shr 24;
  
:= (_ipx[i] and $00FF0000shr 16;
  
:= (_ipx[i] and $0000FF00shr 8;
  
:= (_ipx[i] and $000000FF);
  
// Тут делаем несопрественно преобразования цвета:
  
:= (bdiv 3// это конечно неправильный grayscale, но все же.
  
:= j;
  
:= j;
  
:= j;
  
// Собираем пиксель обратно:
  
_ipx[i] := (and $FFshl 24 or (and $FFshl 16
          
or (and $FFshl 8  or (and $FF);
end;
DrawImage(ImageFromRGB(_iw_ih), 00);
RePaint;
Delay(5000);
end

Со временем я постараюсь расширять список функций (на данный момент некоторые из них невозможно реализовать изза неработающих лейблов и *store команд, которые j-a-s-d собирается исправить в MP3.4).
Так же некоторые функции (такие как изменение размера массива) станут значительно меньше с выходом следующих версий MP.

Если у вас есть идеи, или же вам известны небольшие, полезные Java функции (в виде кода или байт-кодов), говорите.
Хорошего дня :)

cherepets 15.05.2011 12:27

Ответ: [MP3.0+] Магия inline()
 
Молодец)
Правда я так и останусь на 2.02. Люблю писать игры только с "+, -, *" и drawimage.

alexprey 19.05.2011 16:02

Ответ: [MP3.0+] Магия inline()
 
YellowAfterlife, занятная штука. А если сделать не массив integer а допустим какойнить записи. Будет работать?

YellowAfterlife 20.05.2011 08:03

Ответ: [MP3.0+] Магия inline()
 
Вложений: 2
Цитата:

Сообщение от cherepets (Сообщение 188540)
Молодец)
Правда я так и останусь на 2.02. Люблю писать игры только с "+, -, *" и drawimage.

Можно писать и с простыми функциями. Но, как мне кажется, если есть возможность использовать что-то более развитое, то почему бы и нет?
Цитата:

Сообщение от alexprey (Сообщение 188931)
YellowAfterlife, занятная штука. А если сделать не массив integer а допустим какойнить записи. Будет работать?

С небольшими изменениями, да:
PHP код:

program inl;

type
  urecord 
record
    x
real;
    
yreal;
    
anglereal;
    
speedreal;
    
visibleboolean;
  
end;

var 
aim: array[0..1of image;
    
units: array[0..0of urecord;

var 
_r_0:array[0..0of urecord;
// Создает массив указанного размера:
procedure r0_anew(sizeinteger); begin inline(
  
iload_0anewarray class 'R_0'putstatic field 'M''_r_0''[LR_0;';
); 
end;
// Создает и инициализирует новый элемент массива:
procedure r0_new(indexinteger); begin inline(
  
getstatic field 'M''_r_0''[LR_0;'iload_0; new class 'R_0';
  
dupinvokenonvirtual method 'R_0''<init>''()V'aastore;
); 
end;
// Копирует элемент из основного массива во временный:
procedure r0_copy(indexinteger); begin inline(
  
getstatic field 'M''_r_0''[LR_0;'iload_0;
  
getstatic field 'M''units''[LR_0;'iload_0;
  
aaloadaastore;
); 
end;
// Возращает размер основного массива:
function r0_sizeintegerbegin inline(
  
getstatic field 'M''units''[LR_0;'arraylengthireturn;
); 
end;
// Изменяет размер массива:
procedure r0_resize(newsizeinteger);
var 
iinteger;
begin r0_anew(newsize);
  if 
newsize r0_size then for := 0 to r0_size do r0_copy(i);
  else for 
:= 0 to newsize do r0_copy(i);
  if 
newsize r0_size then for := r0_size to newsize do r0_new(i);
inline(
  
getstatic field 'M''_r_0''[LR_0;';
  
putstatic field 'M''units''[LR_0;';
); 
end;

//
procedure AddUnit(indexinteger;xysdreal); begin
  units
[index].:= x;
  
units[index].:= y;
  
units[index].angle := d;
  
units[index].speed := s;
  
units[index].visible := true;
end;

var 
jintegertimage;
begin
  t 
:= LoadImage('/icon.png');
  
r0_resize(16);
  for 
:= 0 to r0_size-do
  
AddUnit(jrandom(getWidth), random(getHeight), random(100)/50+1random(360));
  
repeat
    SetColor
(646464);
    
FillRect(00GetWidthGetHeight);
    for 
:= 0 to r0_size do begin
      units
[j].:= units[j].cos(units[j].angle) * units[j].speed;
      if 
units[j].< -8 then units[j].:= units[j].GetWidth 16;
      if 
units[j].GetWidth+8 then units[j].:= units[j].GetWidth 16;
      
units[j].:= units[j].sin(units[j].angle) * units[j].speed;
      if 
units[j].< -8 then units[j].:= units[j].GetHeight 16;
      if 
units[j].GetHeight+8 then units[j].:= units[j].GetHeight 16;
      
DrawImage(tTrunc(units[j].x)-8Trunc(units[j].y)-8);
    
end;
    if 
GetKeyPressed <> 0 then begin
      r0_resize
(r0_size 1);
      
AddUnit(r0_size-1random(getWidth), random(getHeight), random(100)/50+1random(360));
    
end;
    
RePaint;
    
//Delay(20);
  
forever;
end

Заметка: При компиляции все типы (Record) изменяют названия на R_0, R_1, R_2, и т.д. Тип записи, который задан в исходнике ранее, будет иметь меньший индекс.
Стоит заметить, что с помощью такой системы можно делать весьма и весьма неплохие динамические игры :)

Скриншот и скомпилированный JAR этой демонстрации во вложениях.

IDOL 1234 05.06.2011 18:40

Ответ: [MP3.0+] Магия inline()
 
Т.е. можно использовать МП в качестве компилятора java?

cherepets 05.06.2011 20:09

Ответ: [MP3.0+] Магия inline()
 
java byte

IDOL 1234 06.06.2011 03:44

Ответ: [MP3.0+] Магия inline()
 
O_O
Вы меня пугаете. Или я что-то совершенно неправильно понял.
При чём тут JavaByte?? Это же совсем другая программа. Или вы намекаете на то, что программы, написанные на java, интерпретируются, и слово "компилятор" здесь не вполне корректно?
Собственно, вопрос: сильно ли различается результат обработки одного и того же кода, скормленного МП и, например, Sun One Studio (которая у меня идёт только на виртуалке)?

cherepets 06.06.2011 05:27

Ответ: [MP3.0+] Магия inline()
 
Нет, я про то что в inline надо писать уже в ява-байте.

IDOL 1234 16.06.2011 20:34

Ответ: [MP3.0+] Магия inline()
 
да.. Я жутко ступил.

IDOL 1234 11.07.2011 13:10

Ответ: [MP3.0+] Магия inline()
 
И всё же... ПОЧЕМУ в МП добавили такую ерунду? Была же тема о том, что не помешала бы возможность вставки java - кода. Этого не сделали. Основным аргументом было то, что ПМ предназначен для людей, которые не знают java. Вопрос: вы знаете хоть одного человека, который, не зная java, пишет игрушки(?) на байт-коде? Я не спорю, теоретически это возможно, но на самом деле?? Есть ли хоть какая-то логика в этом мире???? *паника*

cherepets 12.07.2011 22:48

Ответ: [MP3.0+] Магия inline()
 
1) Напиши код на яве
2) Скомпиль его
3) Дизассемблируй его
4) ???
5) ПРОФИТ

Phantom 14.07.2011 00:22

Ответ: [MP3.0+] Магия inline()
 
Я думаю, что вставку непосредственно инструкций в виде байт кода сделали потому, что это было проще и быстрее, чем делать вставку java кода. Хотя не уверен.

IDOL 1234 19.07.2011 18:11

Ответ: [MP3.0+] Магия inline()
 
cherepets (да простят меня админы за такой пост), у меня по какой-то неведомой причине компилятор явы работает чуть менее, чем наполовину. То есть во время установки он ВНЕЗАПНО сообщает, что я прополимерил JVM. ИЧСХ, на виртуалке всё работает, но для нормальной работы не хватает оперативки. Наверное, скоро буду менять windows...
Phantom, может быть, может быть... Только я сомневаюсь, что прикрутить поддержку java-кода было настолько сложно, что за неё никто не захотел браться. Скорее, просто поленились)

Hurrit 19.07.2011 19:35

Ответ: [MP3.0+] Магия inline()
 
лурку для себя открыл штоле наркоман?

IDOL 1234 26.07.2011 16:58

Ответ: [MP3.0+] Магия inline()
 
Нет, это добрая и адекватная реакция на "ПРОФИТ".
А луркоморье я курю уже года джва...


Часовой пояс GMT +4, время: 15:30.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot