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..1] of integer; _iw, _ih, _il: integer;
procedure ImageToRGB(img: image; x, y, w, h: integer);
begin inline(
iload_3; iload_1; isub; putstatic field 'M','_iw','I';
iload 4; iload_2; isub; putstatic 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_0; getstatic field 'M','_ipx','[I';
iconst_0; iload_3; iload_1; iload_2; iload_3; iload 4;
invokevirtual method 'javax/microedition/lcdui/Image','getRGB','([IIIIIII)V';
return;
); 
end;
function 
ImageFromRGB(w, h: integer): image;
begin inline(
getstatic field 'M','_ipx','[I'; iload_0; iload_1; iconst_1;
invokestatic method 'javax/microedition/lcdui/Image','createRGBImage',
'([IIIZ)Ljavax/microedition/lcdui/Image;'; areturn;
); 
end;
//
var i, j, r, g, b, a, p: integer;
begin
j 
:= 10;
i := 0;
while 
i < GetWidth do begin
SetColor
(random(255), random(255), random(255));
FillRect(i, 0, j, GetHeight);
i := i + j;
end;
RePaint;
Delay(1000);
ImageToRGB(ImageFromCanvas(0, 0, GetWidth, 64), 0, 0, GetWidth, 64);
for 
i := 0 to _il-1 do begin
  p 
:= _ipx[i];
  
// Разбираем цвет пикселя на детали:
  
a := (_ipx[i] and $FF000000) shr 24;
  
r := (_ipx[i] and $00FF0000) shr 16;
  
g := (_ipx[i] and $0000FF00) shr 8;
  
b := (_ipx[i] and $000000FF);
  
// Тут делаем несопрественно преобразования цвета:
  
j := (r + g + b) div 3; // это конечно неправильный grayscale, но все же.
  
r := j;
  
g := j;
  
b := j;
  
// Собираем пиксель обратно:
  
_ipx[i] := (a and $FF) shl 24 or (r and $FF) shl 16
          
or (g and $FF) shl 8  or (b and $FF);
end;
DrawImage(ImageFromRGB(_iw, _ih), 0, 0);
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;
    
y: real;
    
angle: real;
    
speed: real;
    
visible: boolean;
  
end;

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

var 
_r_0:array[0..0] of urecord;
// Создает массив указанного размера:
procedure r0_anew(size: integer); begin inline(
  
iload_0; anewarray class 'R_0'; putstatic field 'M', '_r_0', '[LR_0;';
); 
end;
// Создает и инициализирует новый элемент массива:
procedure r0_new(index: integer); begin inline(
  
getstatic field 'M', '_r_0', '[LR_0;'; iload_0; new class 'R_0';
  
dup; invokenonvirtual method 'R_0', '<init>', '()V'; aastore;
); 
end;
// Копирует элемент из основного массива во временный:
procedure r0_copy(index: integer); begin inline(
  
getstatic field 'M', '_r_0', '[LR_0;'; iload_0;
  
getstatic field 'M', 'units', '[LR_0;'; iload_0;
  
aaload; aastore;
); 
end;
// Возращает размер основного массива:
function r0_size: integer; begin inline(
  
getstatic field 'M', 'units', '[LR_0;'; arraylength; ireturn;
); 
end;
// Изменяет размер массива:
procedure r0_resize(newsize: integer);
var 
i: integer;
begin r0_anew(newsize);
  if 
newsize > r0_size then for i := 0 to r0_size - 1 do r0_copy(i);
  else for 
i := 0 to newsize - 1 do r0_copy(i);
  if 
newsize > r0_size then for i := r0_size to newsize - 1 do r0_new(i);
inline(
  
getstatic field 'M', '_r_0', '[LR_0;';
  
putstatic field 'M', 'units', '[LR_0;';
); 
end;

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

var 
j: integer; t: image;
begin
  t 
:= LoadImage('/icon.png');
  
r0_resize(16);
  for 
j := 0 to r0_size-1 do
  
AddUnit(j, random(getWidth), random(getHeight), random(100)/50+1, random(360));
  
repeat
    SetColor
(64, 64, 64);
    
FillRect(0, 0, GetWidth, GetHeight);
    for 
j := 0 to r0_size - 1 do begin
      units
[j].x := units[j].x + cos(units[j].angle) * units[j].speed;
      if 
units[j].x < -8 then units[j].x := units[j].x + GetWidth + 16;
      if 
units[j].x > GetWidth+8 then units[j].x := units[j].x - GetWidth - 16;
      
units[j].y := units[j].y + sin(units[j].angle) * units[j].speed;
      if 
units[j].y < -8 then units[j].y := units[j].y + GetHeight + 16;
      if 
units[j].y > GetHeight+8 then units[j].y := units[j].y - GetHeight - 16;
      
DrawImage(t, Trunc(units[j].x)-8, Trunc(units[j].y)-8);
    
end;
    if 
GetKeyPressed <> 0 then begin
      r0_resize
(r0_size + 1);
      
AddUnit(r0_size-1, random(getWidth), random(getHeight), random(100)/50+1, random(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, время: 12:22.

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